开启掘金成长之旅!这是我参与「掘金日新计划 · 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;
}