Codeforces Round #841 (Div. 2) C E

C. Even Subarrays

C题做法就是对于一个数我们check整个序列里的substring只需要O(n)
不管是XOR还是加减
我们只需要记录一个前缀和
然后枚举每一个R看他是否存在一个L有过区间等于这个数
然后我们可以知道完全平方数不超过500个
就直接500n做完了

void solve(){
    int n;cin>>n;
    vector<int>a(n+1),s(n+1),mp(4*n+1);
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=s[i-1]^a[i];
    }
    int ans=n*(n+1)/2;
    mp[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=0;j*j<=2*n;j++){
            ans-=mp[(j*j)^s[i]];
        }
        mp[s[i]]++;
    }
    cout<<ans<<endl;
}

E. Graph Cost

关键是如何快速计算1到n之间每对的gcd是多少
我们gcd为x
那么只有可能为
x 2x 3x...
之间才能构成这个x
但是2x与4x之间肯定是2x
3x和6x
我们假设dp[i]为gcd为i的对数
那么我们只需要减去2i 3i...即可

void solve(){
    int n,m;cin>>n>>m;
    vector<int>a(n+1);
    int ans=0;
    for(int i=n;i>=2;i--){
        int k=i-1;
        a[i]=(n/i)*(n/i-1)/2;
        for(int j=2*i;j<=n;j+=i)a[i]-=a[j];
        int now=a[i];
        while(now>=k&&m>=k){
            now-=k;
            m-=k;
            ans+=k+1;
        }
    }
    if(!m)cout<<ans<<endl;
    else cout<<-1<<endl;
}
posted @ 2022-12-28 20:41  ycllz  阅读(32)  评论(0)    收藏  举报