A. Tit for Tat
半个小时都在读假题wssb
全都加到
a
n
−
1
a_{n-1}
an−1即可
void solves(){
int n,k;cin>>n>>k;
for(int i=0;i<n;++i) cin>>a[i];
for(int i=0;i<n;++i){
if(a[i]){
if(i==n-1)break;
if(a[i]<=k){
a[n-1]+=a[i];
k-=a[i];
a[i]=0;
} else{
a[i]-=k;
a[n-1]+=k;
break;
}
}
}
for(int i=0;i<n;++i) cout<<a[i]<<" ";cout<<endl;
}
B. AGAGA XOOORRR
假设
a
n
a_n
an最后经过一系列XOR后可得到最长相同序列,记此序列为
b
m
b_m
bm
(
m
≥
2
)
(m\geq2)
(m≥2)。
1.当
m
m
m为偶数时,显然偶数个相同的整数异或结果为0。
2.当m为奇数时,
m
≥
3
m\geq3
m≥3,且可将
b
m
b_m
bm分为长度为奇数的三段分别异或,得到
c
k
,
(
k
=
3
)
c_k,(k=3)
ck,(k=3)。
如:
[
b
m
=
5
,
5
,
5
,
5
,
5
,
5
,
5
]
[b_m=5,5,5,5,5,5,5]
[bm=5,5,5,5,5,5,5] ,其中m=7.
分成三个奇数长度的段分别XOR:
[
b
m
=
【
5
】
,
【
5
,
5
,
5
】
,
【
5
,
5
,
5
】
]
[b_m=【5】,【5,5,5】,【5,5,5】]
[bm=【5】,【5,5,5】,【5,5,5】]
得到
[
c
k
=
5
,
5
,
5
]
[c_k=5,5,5]
[ck=5,5,5]。
即只要
a
n
a_n
an可以分成至少三段,且三段的XOR值均等于
a
n
a_n
an的XOR值即可。
在计算三段XOR值时可以先预处理一下前缀。
void solves(){
int n;cin>>n;
memset(b,0,sizeof(b));
ll ans=0;
for(int i=1;i<=n;++i){
cin>>a[i];
b[i]=b[i-1]^a[i];
ans^=a[i];
}
int flag=0;
if(!ans){
cout<<"YES\n";
} else{
for(int i=1;i<n;++i){
for(int j=i+1;j<n;++j){
if((b[i]^b[0])==ans&&(b[j]^b[i])==ans&&(b[n]^b[j])==ans){
flag=1;
}
}
}
cout<<( flag ? "YES":"NO")<<endl;
}
}
或者换另外一种更简单的写法
void solves(){
int n;cin>>n;
ll ans=0;
for(int i=1;i<=n;++i){
cin>>a[i];
ans^=a[i];
}
int flag=0;
if(!ans){
cout<<"YES\n";
} else{
ll cnt=0,sum=0;
for(int i=1;i<=n;++i){
sum^=a[i];
if(sum==ans) sum=0,++cnt;
}
cout<<( (sum==0&&cnt>=3) ? "YES":"NO")<<endl;
}
}
C. Baby Ehab Partitions Again
1.当
∑
a
n
\sum a_n
∑an为奇数时显然为0。
2.当
∑
a
n
\sum a_n
∑an为偶数时,可01背包求得是否满足均分。若不满足显然为0。
若满足 。。。满足的话我一开始也没思路。。。
我们把所有数字考虑成二进制,发现
10+10 =100
10 + 11 = 101
10+ 100 = 110
10 + 101 = 111
发现没有,只有加数中的最低位有1的时候结果最低为才会出现1
比如要想让倒数第二位出现1,加数中倒数第二位要有1,或者加数中最后一个能进位这样倒数第二位才能出现1.
那如果不能进位呢?是不是这个位置就不能通过别的途径来代替了
我们可以通过求lowbit最小的元素将这个删掉就一定不能再分为两组了。
比如有个元素6二进制110,他的假设他的lowbit是最低的也就是说所有元素的lowbit最小是(10)2 这样就不可能出现1+1=10的情况了,不然lowbit就是1了。这样这个10的作用就是无可替代的。假设原来的数组分为了两组,总和都是xxxxx10
————————————————
版权声明:本文为CSDN博主「六月陌」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30445397/article/details/116003694
qaq看看这个大佬的想法吧👆,挺直击本质的。包括我看见其它的将 a n a_n an不断除2寻找奇数的解法,本质上也是为了寻找最小的lowbit。
inline int lowbit(int x){
return x&-x;
}
void solves(){
int n;cin>>n;
vector<int>a(n+7);
ll sum=0;
for(int i=0;i<n;++i){
cin>>a[i];
sum+=a[i];
}
if(sum&1){
cout<<0<<endl;
} else{
vector<int>dp(sum,0);
for(int i=0;i<n;++i){
for(int j=sum/2;j>=a[i];--j){
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
}
}
if(dp[sum/2]!=sum/2){
cout<<0<<endl;
} else{
cout<<1<<endl;
int idx=-1,mm=0x3f3f3f3f;
for(int i=0;i<n;++i){
if(lowbit(a[i])<mm){
mm=lowbit(a[i]);
idx=i;
}
}
cout<<idx+1<<endl;
}
}
}