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

xuanxuan001
生活就像愤怒的小鸟,失败后总有几只猪在笑。搬运于
2025-08-24 23:02:34,当前版本为作者最后更新于2024-08-24 20:10:21,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
抽象的官解,爽飞的四天。
发现两种操作都是整体的批量操作而没有针对单点的,所以感性理解一下这些操作是很不“自由”的,推理一下发现确实如此。
由于 D 操作针对元素而不是序列,所以下面直接认为序列是所有为 位置构成的集合, 表示对 进行一次 D 操作后的集合。
首先,如果进行了一次 D 操作后,那么再次进行 D 操作不会改变,但如果取反(就是 B 操作,这么说直观一些,下同)后会发现只要它不是空集,那么它就拥有至少一半的元素(即值是 )。那么猜想这个序列进行一次 D 操作后一定会变成全集,证明如下:
发现所有的情况都严格不劣于恰有 个元素的情况,也就是操作前的集合(设它为 )的线性基大小为 。那么此时不妨设线性基中没有 (即最高位是 )。那么取反后一定满足 在集合里面,而 一定有 或 ,因此如果再进行一次 D 操作就一定有 ,因此可知 。
同样的,也可以得到 和它的补集中至少有一个进行 D 变换后会变成全集。
那么有了这些结论,就不难发现可能的集合只有 种,经过梳理,发现有八种:
- 及其补集(即 B 操作,下同)。
- 或 及其补集。
- 及其补集。
对于第五条的解释:。
因此只需要用一个数就能存储整个集合,并实现 单次变换和查询。
其实这里跟官解前面的那些观察差不多。
每次需要变换一个区间,这是容易维护的,线段树即可维护,记录每个节点的函数值以及每种数列的经过次数即可。总复杂度 ,把 认为和 同阶的话甚至刚好平衡了,不用上猫树。
可能复杂度有些高?官解最后靠循环节直接计算倒也是个思路,主要是利用了 BD 两个操作连续进行多次都没有意义,幸好没卡我的。
但我觉得代码复杂度肯定是我优。代码
#include<cstdio> #define TY int #define MAXN 262144 #define FOR(i,a,b) for(TY i=(a);i<=(b);i=-~i) #define fOR(i,a,b) for(TY i=(a);i<(b);i=-~i) #define ROF(i,a,b) for(TY i=(a);i>=(b);i=~-i) #define rOF(i,a,b) for(TY i=(a);i>(b);i=~-i) #define EDG(i,u) for(TY i=hed[u];i;i=nxt[i]) using namespace std; typedef long long ll; const TY M=998244353; typedef unsigned long long ull; TY _abs(TY a){return a<0?-a:a;} TY maxn(TY a,TY b){return a>b?a:b;} TY minn(TY a,TY b){return a<b?a:b;} inline void updmx(TY &x,TY y){if(x<y)x=y;} inline void updmn(TY &x,TY y){if(x>y)x=y;} inline void add(TY &x,TY y){if((x+=y)>=M)x-=M;} TY gcd(TY a,TY b){return b?gcd(b,a%b):a;} TY qp(TY a,TY b){TY ans=1;do{if(1&b)ans=ans*a%M;a=a*a%M;}while(b>>=1);return ans;} char getc(){char ch=getchar();while(ch==' '||ch=='\n'||ch=='\r')ch=getchar();return ch;} TY qr(){ char ch=getchar();TY s=0,x=1; for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')x=-1; for(;ch>='0'&&ch<='9';ch=getchar())s=s*10+ch-'0';return x*s; }void qw(TY a){if(a>9)qw(a/10);putchar(a%10+'0');} void qw(TY a,char ch){ if(a<0){a=-a;putchar('-');} if(a>9)qw(a/10);putchar(a%10+'0'); if(ch)putchar(ch); }TY n,m,T,b[MAXN],ct,kd,x,l,r,to[2][8],ar[18],nm,tot[MAXN][8],vl[8],ans; TY tre[MAXN<<1][8],sm[MAXN<<1][8][8],tmp[8]; bool a[MAXN],t[MAXN];char s[MAXN]; //集合编号按题解中列举顺序,0代表B变换,1代表D变换 void ins(TY x){ ROF(i,n-1,0)if((1<<i)&x){ if(ar[i]){x^=a[i];continue;} ar[i]=x;++nm;return; } }void dfs(TY x,TY v){ if(x==n){t[v]=true;return;} dfs(x+1,v);if(ar[x])dfs(x+1,v^ar[x]); }void build(TY i,TY j,TY id){ if(i==j){ if(s[i]=='B')fOR(i,0,8){ tre[id][i]=to[0][i]; sm[id][i][to[0][i]]=1; }else fOR(i,0,8){ tre[id][i]=to[1][i]; sm[id][i][to[1][i]]=1; }return; }TY mid=i+j>>1,sn=id<<1; build(i,mid,sn);build(mid+1,j,sn|1); fOR(i,0,8){ tre[id][i]=tre[sn|1][tre[sn][i]]; fOR(j,0,8)sm[id][i][j]=sm[sn][i][j]+sm[sn|1][tre[sn][i]][j]; } }void ask(TY i,TY j,TY id){ if(l<=i&&j<=r){ fOR(i,0,8)tmp[i]+=sm[id][x][i]; x=tre[id][x];return; }TY mid=i+j>>1; if(l<=mid)ask(i,mid,id<<1); if(r>mid)ask(mid+1,j,id<<1|1); }int main(){ fOR(i,0,8)to[0][i]=i^1; to[1][2]=2;to[1][3]=4; to[1][4]=4;to[1][5]=6; to[1][6]=6;to[1][7]=4; n=qr();m=qr();T=qr(); fOR(i,0,1<<n)a[i]=qr();scanf("%s",s+1); if(n==1){to[1][0]=0;to[1][1]=1;}//n=1需要特殊考虑 else{ fOR(i,0,1<<n)if(a[i])ins(i); if(nm==n)to[1][0]=4; else{dfs(0,0);to[1][0]=2;} fOR(i,nm=0,n)ar[i]=0; fOR(i,0,1<<n)if(!a[i])ins(i); if(nm==n)to[1][1]=4; else{dfs(0,0);to[1][1]=2;} }fOR(i,0,1<<n)if(a[i])++vl[0];vl[1]=(1<<n)-vl[0]; fOR(i,0,1<<n)if(t[i])++vl[2];vl[3]=(1<<n)-vl[2]; vl[4]=1<<n;vl[6]=1;vl[7]=(1<<n)-1;build(1,m,1); while(T--){ kd=qr(); if(kd==2){ x=qr();l=qr(); switch(b[x]){ case 0:qw(a[l],'\n');break; case 1:qw(a[l]^1,'\n');break; case 2:qw(t[l],'\n');break; case 3:qw(t[l]^1,'\n');break; case 4:printf("1\n");break; case 5:printf("0\n");break; case 6:qw(!l,'\n');break; case 7:qw(!!l,'\n');break; }continue; }if(kd==1){ x=qr();l=qr();r=qr();x=b[x]; fOR(i,0,8)tmp[i]=0;ask(1,m,1); b[++ct]=x;qw(vl[b[ct]],'\n'); fOR(i,0,8)tot[ct][i]=tmp[i]; }else{ x=qr();l=qr();ans=tot[x][4]; if(a[l])ans+=tot[x][0];else ans+=tot[x][1]; if(t[l])ans+=tot[x][2];else ans+=tot[x][3]; if(l)ans+=tot[x][7];else ans+=tot[x][6];qw(ans,'\n'); } }return 0; }
- 1
信息
- ID
- 8589
- 时间
- 1200ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者