1 条题解
-
0
自动搬运
来自洛谷,原作者为

jun头吉吉
alive搬运于
2025-08-24 22:47:42,当前版本为作者最后更新于2023-05-30 16:14:35,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意
给定 ,长度为 的序列 和 ,其中 , 由 个与(&), 个或(|), 个异或(^)组成,现在 ,现在你需要重排 和 使得 最大,给出最大值并构造一组方案。
多测,。
题解
我的做法好麻烦不知道有没有高论喵。
设 表示序列 中 出现的次数, 表示 的 的个数, 表示 的个数, 表示最小的 的 。
首先如果 ,那么不存在与操作,一位如果希望是 ,要么 是奇数,否则就需要用掉至少一次或操作。从高位往低位做,优先保证高位是一即可。
然后如果 ,那么最多只有 位能够是 ,取高 位即可。
否则我们有一种除了 位其他所有出现的位都是 的策略就是先与 ,然后剩下的所有位再与操作之后或/异或一次,剩下的操作全部丢到与 之前即可。
所以我们现在的目标是判断能否全部出现的位都是 。
一个最简单的情况是 ,因为我们可以连续与两个不同的数把所有位清零,之后就所有位都或/异或一次,剩下的操作丢到两次与之前即可。
否则的话我们可以断言,每次与操作后面跟着的数都是相同的,假设是 。因为我们需要保证第 位为一,所以首先要有 ,然后我们的构造方案还是类似的,仍然是其他位在之后或/异或一次(优先选择异或),那么如果 ,那么对于 肯定可以被或一下,因此肯定可行。否则只有与和异或操作,那么一个条件就是 是奇数,那么这位肯定是 ,否则就是不行。
然后只要模拟一下就行了叭。
代码
int T,n,x,y,z,c,cc,a[N],buc[N]; #define _(X,a,b) op##X.pb(a),nums##X.pb(b),buc[b]--,(a=='&'?x:a=='|'?y:z)-- #define AA(i) _(A,'&',i) #define AO(i) _(A,'|',i) #define AX(i) _(A,'^',i) #define BA(i) _(B,'&',i) #define BO(i) _(B,'|',i) #define BX(i) _(B,'^',i) #define rev(X) reverse((X).begin(),(X).end()) signed main(){ read(T);for(int testcase=1;testcase<=T;testcase++){ read(n,x,y,z);for(int i=0;i<n;i++)buc[i]=0; for(int i=1;i<=n;i++)read(a[i]),buc[a[i]]++; vector<int>opA,numsA,opB,numsB; if(x==0){ for(int i=n-1;~i;i--)if(buc[i]){ if(buc[i]%2||y){ pc('1');int _=buc[i]%2?0:1; while(buc[i]>_&&z)AX(i); while(buc[i])AO(i); }else{pc('0');while(buc[i])AX(i);} }else pc('0'); goto end; }else{ c=cc=0;for(int i=0;i<n;i++)c+=buc[i]>0,cc+=buc[i]>1; if(y+z<c){ for(int i=n-1;~i;i--)if(buc[i]&&(y||z)){ pc('1');if(y)BO(i);else BX(i); }else pc('0'); goto end; } if(x>=2&&cc>=2){ for(int i=0;i<n;i++)if(buc[i]>1)for(int j=i+1;j<n;j++)if(buc[j]>1){ BA(i);BA(j); for(int k=n-1;~k;k--)if(buc[k]){ pc('1');if(y)BO(k);else BX(k); }else pc('0'); goto end; } } for(int i=0;i<n;i++)if(buc[i]>x&&(y||(buc[i]-x)%2)){ for(int j=n-1;~j;j--)if(buc[j]){ pc('1');if(i!=j){if(z)BX(j);else BO(j);} }else pc('0'); if(y){BA(i);rev(opB);rev(numsB);BO(i);} else{while(x)BA(i);rev(opB);rev(numsB);while(buc[i])BX(i);} goto end; } for(int mn=0;mn<n;mn++)if(buc[mn]){ for(int j=n-1;~j;j--)pc('0'+(buc[j]&&j!=mn)); BA(mn); for(int j=0;j<n;j++)if(buc[j]&&j!=mn){if(y)BO(j);else BX(j);} goto end; } } end:pc('\n'); for(int i=0;i<n;i++)while(buc[i]){if(x)AA(i);else if(y)AO(i);else AX(i);} for(uint i=0;i<opA.size();i++)pc(opA[i]); for(uint i=0;i<opB.size();i++)pc(opB[i]); pc('\n'); for(uint i=0;i<numsA.size();i++)write(numsA[i]),pc(' '); for(uint i=0;i<numsB.size();i++)write(numsB[i]),pc(' '); pc('\n'); } }
- 1
信息
- ID
- 8790
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者