Codeforces Round #447 Div. 2 A.B.C

补题补题……实在是太弱了orz(○| ̄|_ ) 就是因为弱才要更努力啊=w=

(补完这波该收拾收拾准备考试了……莫名马上就到期中考试周了orz)

A.QAQ

大爱出题人呐=w=,配图是宝石之国!超赞!

题意是求“QAQ”子串的个数……数一数一共多少个A,然后记录一下,每个A左边有多少个Q就好了,A右边Q的个数是nQ-cntQ[i],结果就是∑nQ[i]*(nQ-cntQ[i]);

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
string s;
int nQ=0;
int cntQ[105];
int main()
{
    cin>>s;
    int crt=0;
    for(int i=0;i<s.length();i++)
    {
        if(s[i]=='A')
            cntQ[crt++]=cnt0;
        if(s[i]=='Q') nQ++;
    }
    ll ans=0;
    for(int i=0;i<crt;i++)
        ans+=cntQ[i]*(nQ-cntQ[i]);
    cout<<ans<<endl;
    return 0;
}

B.Ralph And His Magic Field

emmmmm给出一个n*m的矩阵还有每行每列的乘积,去填充1或者-1,求总共有多少种填充的方法  //为什么这么显而易见的问题会卡那么久orz

假设前(n-1)*(m-1)已经填充好了,不管乘积是1还是-1,我们总能找到一种填充方法使得满足题意,因此答案就是mod_pow(2,(n-1)*(m-1));

//需要注意的是,(n-1)*(m-1)会爆long long,记得拆分开计算……(orz没注意,然后被hack,心痛)

//还有就是,n,m不是同奇同偶的时候,如果乘积要求为-1,是无法找到满足题意的方法的,此时输出0

(画一画比较好想,比如一个n*m(n<m)的矩阵,我们把左上角n*n的矩阵的对角线填充为-1,此时保证n行的乘积均为-1,可是却无法在第m列填充-1使得第i行乘积为-1)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll n,m,k;
ll modpow(ll a,ll k)
{
   ll  ans=1;
    while(k)
    {
        if(k&1) ans=(ans*a)%mod;
        a=(a*a)%mod;
        k>>=1;
    }
    return ans;
}
int main()
{
    cin>>n>>m>>k;
    int a=n%2,b=m%2;
    if(a!=b&&k==-1)
        cout<<"0"<<endl;
    else
    {
    ll ans1=modpow(2,n-1)%mod;
    ll ans2=modpow(ans1,m-1)%mod;
    cout<<ans2<<endl;
    }
    return 0;
}

C.Marco and GCD Sequence

tutorial:

If the minimum element isn't the gcd of the given set, the answer is -1. Otherwise, we can insert the minimum element between two consecutive elements of the set. And the length of the sequence is 2n - 1 which satisfies the constraints.

(我真的……想不到要这么做……绝望orz)

 判断-1的情况还是比较好想的,如果当前序列的gcd都不在序列里,那肯定找不到满足题意的原序列。

然后……在每两个元素之前插入当前序列的最小元素,然后就可以构造出一个满足题意的原序列……

毕竟题目里没说元素不可以重复,只是在求gcd的时候只保留一个……

后我就exm??一脸懵逼,我还想着怎么删减元素找原序列……想想就……是我zz……)

不过其实想想也是……为什么会觉得原序列为什么就一定要比当前序列短呢??明明原序列的所有元素都应该在当前序列里,有i<=j……

明明原序列的元素一定在当前序列里,然后我们只需要把当前序列中的最小公倍数填充进去就可以保证当前序列是原序列的任意段gcd的集合……

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int n,s[N];
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>s[i];
    for(int i=1;i<n;i++)
        if(s[i]%s[0]!=0)
    {
        cout<<"-1"<<endl;
        return 0;
    }
    cout<<2*n-1<<endl;
    for(int i=0;i<n;i++)
    {
        cout<<s[i];
        i==n-1?cout<<endl:cout<<" "<<s[0]<<" ";
    }
    return 0;
}

 D……待补……

原文地址:https://www.cnblogs.com/Egoist-/p/7867084.html