C - Zero-Sum Prefixes,D - ConstructOR 构造

91 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情

C - Zero-Sum Prefixes 前缀和

可以看出0会把整个数组分割成一些区间,假设0的位置为z1,z2...zm,那么数组就可以分成 a[1]...a[z1-1],a[z1]...a[z2-1].... 然后又可以发现这些区间都是独立的,那如果要想每个区间的价值最大,那就要把区间一开始的0改为出现次数最多的一个前缀和就可以了

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define pause system("pause")
using namespace std;
const int N=2e5+5;
ll qpow(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
int t,n,a[N];
map<int,int>mp;
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--)
    {
        cin>>n;
        mp.clear();
        int flag=0,sum=0,maxx=0,ans=0;
        for(int i=1;i<=n;i++) cin>>a[i];a[n+1]=0;
        for(int i=1;i<=n+1;i++)
        {
            sum+=a[i];
            if(a[i]==0)
            {
                if(!flag) ans+=mp[0],flag=1;
                else ans+=maxx;
                mp.clear();
                maxx=0;
            }
            mp[sum]++;
            maxx=max(maxx,mp[sum]);
        }
        cout<<ans<<endl;
    }
    pause;
    return 0;
}

D - ConstructOR 构造

构造出一个x使得x|a=x|b=x且x%d==0就可以,一开始让y=a|b,x=0,为了让x|a=a,x|b=b,那么y某位有1,x一定也要有1才可以,为了让x%d==0,x+=d<<k,也就是让d平移k位使得x的那一位上有1,那一定是让d的最低位的1来对齐这个1,如果不是最低位的话可能会出现x的这一位没有被或上1的情况,看样例6 8 14就知道了

#include<bits/stdc++.h>
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
#define pause system("pause")
using namespace std;
const int N=2e5+5;
ll qpow(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
int t,a,b,d;
signed main()
{
    //ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>d;
        int x=a|b;
        if(lowbit(x)<lowbit(d))
        {
            cout<<"-1\n";
            continue;
        }
        int ans=0,cnt=__builtin_ctzll(d);
        for(int i=0;i<30;i++)
            if((ans>>i&1)==0&&(x>>i&1)) ans+=d<<(i-cnt);
        cout<<ans<<endl;
    }
    pause;
    return 0;
}