noip模拟测试11
T1:string
第一眼秒出思路,这不就是排序那道题的加强版吗?
然而歪?解复杂度虽然是对的,但常数过大,竟被卡到70
歪?解:(实际上std写的就是这个,但据说std被卡掉了 OAO)
因为字符集很小,所以我们可以把区间排序改为区间查询和覆盖
即:先查询区间内所有字符的个数,再从左端点开始按照大小关系依次将长度为字符个数的区间修改为该字符。
期望复杂度O ( 26*mlogn ),实际复杂度O ( 26*mlogn*(巨大的常数) )
所以需要一(feng)定(kuang)的卡常
正?解:
因为字符集很小,所以重复字符很多,又因为我们的操作是排序,所以操作后字符显然会变为一块一块的
所以可以在线段树上每个节点记录段内字符是否全部相等
若相等直接return,否则向下递归
这样直接递归看起来似乎单次复杂度不太对
但是仔细一想会发现,对于较短的区间操作来说,整块字符较少,递归次数较多,但区间短,所以复杂度正确
对于较长的区间操作来说,整块字符较多,递归次数较少,虽区间长,但复杂度仍正确
所以均摊复杂度正确,可过(还跑的挺快???)
so,歪?解 code
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<vector> 7 #include<cmath> 8 using namespace std; 9 const int MAXN=100105; 10 int n,m,tmp[30],ls[MAXN*2],rs[MAXN*2],sum[MAXN*2][26],tag[MAXN*2],tot,lst,root; 11 char s[MAXN]; 12 void build(int &p,int l,int r) { 13 if(!p) p=++tot; 14 if(l==r) return (void) (sum[p][s[l]-'a'+1]=1); 15 int mid=(l+r)>>1; 16 build(ls[p],l,mid),build(rs[p],mid+1,r); 17 for(int i=1;i<=26;i++) sum[p][i]=sum[ls[p]][i]+sum[rs[p]][i]; 18 } 19 int ask(int p,int l,int r,int ql,int qr,int k) { 20 if(ql==l&&qr==r) return sum[p][k]; 21 int mid=(l+r)>>1; 22 if(tag[p]) { 23 for(int i=1;i<=26;i++) sum[ls[p]][i]=0; 24 for(int i=1;i<=26;i++) sum[rs[p]][i]=0; 25 sum[ls[p]][tag[p]]=mid-l+1; 26 sum[rs[p]][tag[p]]=r-mid; 27 tag[ls[p]]=tag[rs[p]]=tag[p]; 28 tag[p]=0; 29 } 30 if(qr<=mid) return ask(ls[p],l,mid,ql,qr,k); 31 else if(ql>mid) return ask(rs[p],mid+1,r,ql,qr,k); 32 else return ask(ls[p],l,mid,ql,mid,k)+ask(rs[p],mid+1,r,mid+1,qr,k); 33 } 34 void change(int p,int l,int r,int ql,int qr,int k) { 35 if(ql==l&&qr==r) { 36 for(int i=1;i<=26;i++) sum[p][i]=0; 37 sum[p][k]=r-l+1; tag[p]=k; 38 return; 39 } 40 int mid=(l+r)>>1; 41 if(tag[p]) { 42 for(int i=1;i<=26;i++) sum[ls[p]][i]=0; 43 for(int i=1;i<=26;i++) sum[rs[p]][i]=0; 44 sum[ls[p]][tag[p]]=mid-l+1; 45 sum[rs[p]][tag[p]]=r-mid; 46 tag[ls[p]]=tag[rs[p]]=tag[p]; 47 tag[p]=0; 48 } 49 if(qr<=mid) change(ls[p],l,mid,ql,qr,k); 50 else if(ql>mid) change(rs[p],mid+1,r,ql,qr,k); 51 else change(ls[p],l,mid,ql,mid,k),change(rs[p],mid+1,r,mid+1,qr,k); 52 for(int i=1;i<=26;i++) sum[p][i]=sum[ls[p]][i]+sum[rs[p]][i]; 53 } 54 void print(int p,int l,int r) { 55 if(l==r) { 56 for(int i=1;i<=26;i++) 57 if(sum[p][i]) printf("%c",i+'a'-1); 58 return; 59 } 60 int mid=(l+r)>>1; 61 if(tag[p]) { 62 for(int i=1;i<=26;i++) sum[ls[p]][i]=0; 63 for(int i=1;i<=26;i++) sum[rs[p]][i]=0; 64 sum[ls[p]][tag[p]]=mid-l+1; 65 sum[rs[p]][tag[p]]=r-mid; 66 tag[ls[p]]=tag[rs[p]]=tag[p]; 67 tag[p]=0; 68 } 69 print(ls[p],l,mid),print(rs[p],mid+1,r); 70 } 71 int main() { 72 scanf("%d%d%s",&n,&m,s+1); 73 build(root,1,n); 74 for(int i=1,o,tl,tr;i<=m;i++) { 75 scanf("%d%d%d",&tl,&tr,&o); 76 lst=tl; 77 for(int j=1;j<=26;j++) tmp[j]=ask(root,1,n,tl,tr,j); 78 if(!o) { 79 for(int j=26;j>=1;j--) 80 if(tmp[j]) { 81 change(root,1,n,lst,lst+tmp[j]-1,j); 82 lst+=tmp[j]; 83 } 84 } else { 85 for(int j=1;j<=26;j++) 86 if(tmp[j]) { 87 change(root,1,n,lst,lst+tmp[j]-1,j); 88 lst+=tmp[j]; 89 } 90 } 91 } 92 print(root,1,n); 93 printf("\n"); 94 return 0; 95 }
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<vector> 7 #include<cmath> 8 using namespace std; 9 const int MAXN=100001; 10 int n,m,tmp[30],ls[MAXN*2],rs[MAXN*2],sum[MAXN*2][26],tag[MAXN*2],tot,lst,root; 11 char s[MAXN]; 12 void build(int &p,int l,int r) { 13 if(!p) p=++tot; 14 if(l==r) return (void) (sum[p][s[l]-'a'+1]=1); 15 int mid=(l+r)>>1; 16 build(ls[p],l,mid),build(rs[p],mid+1,r); 17 sum[p][1]=sum[ls[p]][1]+sum[rs[p]][1];sum[p][2]=sum[ls[p]][2]+sum[rs[p]][2]; 18 sum[p][3]=sum[ls[p]][3]+sum[rs[p]][3];sum[p][4]=sum[ls[p]][4]+sum[rs[p]][4]; 19 sum[p][5]=sum[ls[p]][5]+sum[rs[p]][5];sum[p][6]=sum[ls[p]][6]+sum[rs[p]][6]; 20 sum[p][7]=sum[ls[p]][7]+sum[rs[p]][7];sum[p][8]=sum[ls[p]][8]+sum[rs[p]][8]; 21 sum[p][9]=sum[ls[p]][9]+sum[rs[p]][9];sum[p][10]=sum[ls[p]][10]+sum[rs[p]][10]; 22 sum[p][11]=sum[ls[p]][11]+sum[rs[p]][11];sum[p][12]=sum[ls[p]][12]+sum[rs[p]][12]; 23 sum[p][13]=sum[ls[p]][13]+sum[rs[p]][13];sum[p][14]=sum[ls[p]][14]+sum[rs[p]][14]; 24 sum[p][15]=sum[ls[p]][15]+sum[rs[p]][15];sum[p][16]=sum[ls[p]][16]+sum[rs[p]][16]; 25 sum[p][17]=sum[ls[p]][17]+sum[rs[p]][17];sum[p][18]=sum[ls[p]][18]+sum[rs[p]][18]; 26 sum[p][19]=sum[ls[p]][19]+sum[rs[p]][19];sum[p][20]=sum[ls[p]][20]+sum[rs[p]][20]; 27 sum[p][21]=sum[ls[p]][21]+sum[rs[p]][21];sum[p][22]=sum[ls[p]][22]+sum[rs[p]][22]; 28 sum[p][23]=sum[ls[p]][23]+sum[rs[p]][23];sum[p][24]=sum[ls[p]][24]+sum[rs[p]][24]; 29 sum[p][25]=sum[ls[p]][25]+sum[rs[p]][25];sum[p][26]=sum[ls[p]][26]+sum[rs[p]][26]; 30 } 31 void ask(int p,int l,int r,int ql,int qr) { 32 if(ql==l&&qr==r) { 33 tmp[1]+=sum[p][1];tmp[2]+=sum[p][2];tmp[3]+=sum[p][3];tmp[4]+=sum[p][4]; 34 tmp[5]+=sum[p][5];tmp[6]+=sum[p][6];tmp[7]+=sum[p][7];tmp[8]+=sum[p][8]; 35 tmp[9]+=sum[p][9];tmp[10]+=sum[p][10];tmp[11]+=sum[p][11];tmp[12]+=sum[p][12]; 36 tmp[13]+=sum[p][13];tmp[14]+=sum[p][14];tmp[15]+=sum[p][15];tmp[16]+=sum[p][16]; 37 tmp[17]+=sum[p][17];tmp[18]+=sum[p][18];tmp[19]+=sum[p][19];tmp[20]+=sum[p][20]; 38 tmp[21]+=sum[p][21];tmp[22]+=sum[p][22];tmp[23]+=sum[p][23];tmp[24]+=sum[p][24]; 39 tmp[25]+=sum[p][25];tmp[26]+=sum[p][26]; 40 return; 41 } 42 int mid=(l+r)>>1; 43 if(tag[p]) { 44 sum[ls[p]][1]=0;sum[ls[p]][2]=0;sum[ls[p]][3]=0;sum[ls[p]][4]=0; 45 sum[ls[p]][5]=0;sum[ls[p]][6]=0;sum[ls[p]][7]=0;sum[ls[p]][8]=0; 46 sum[ls[p]][9]=0;sum[ls[p]][10]=0;sum[ls[p]][11]=0;sum[ls[p]][12]=0; 47 sum[ls[p]][13]=0;sum[ls[p]][14]=0;sum[ls[p]][15]=0;sum[ls[p]][16]=0; 48 sum[ls[p]][17]=0;sum[ls[p]][18]=0;sum[ls[p]][19]=0;sum[ls[p]][20]=0; 49 sum[ls[p]][21]=0;sum[ls[p]][22]=0;sum[ls[p]][23]=0;sum[ls[p]][24]=0; 50 sum[ls[p]][25]=0;sum[ls[p]][26]=0; 51 sum[rs[p]][1]=0;sum[rs[p]][2]=0;sum[rs[p]][3]=0;sum[rs[p]][4]=0; 52 sum[rs[p]][5]=0;sum[rs[p]][6]=0;sum[rs[p]][7]=0;sum[rs[p]][8]=0; 53 sum[rs[p]][9]=0;sum[rs[p]][10]=0;sum[rs[p]][11]=0;sum[rs[p]][12]=0; 54 sum[rs[p]][13]=0;sum[rs[p]][14]=0;sum[rs[p]][15]=0;sum[rs[p]][16]=0; 55 sum[rs[p]][17]=0;sum[rs[p]][18]=0;sum[rs[p]][19]=0;sum[rs[p]][20]=0; 56 sum[rs[p]][21]=0;sum[rs[p]][22]=0;sum[rs[p]][23]=0;sum[rs[p]][24]=0; 57 sum[rs[p]][25]=0;sum[rs[p]][26]=0; 58 sum[ls[p]][tag[p]]=mid-l+1; 59 sum[rs[p]][tag[p]]=r-mid; 60 tag[ls[p]]=tag[rs[p]]=tag[p]; 61 tag[p]=0; 62 } 63 if(qr<=mid) ask(ls[p],l,mid,ql,qr); 64 else if(ql>mid) ask(rs[p],mid+1,r,ql,qr); 65 else ask(ls[p],l,mid,ql,mid),ask(rs[p],mid+1,r,mid+1,qr); 66 } 67 void change(int p,int l,int r,int ql,int qr,int k) { 68 if(ql==l&&qr==r) { 69 sum[p][1]=0;sum[p][2]=0;sum[p][3]=0;sum[p][4]=0; 70 sum[p][5]=0;sum[p][6]=0;sum[p][7]=0;sum[p][8]=0; 71 sum[p][9]=0;sum[p][10]=0;sum[p][11]=0;sum[p][12]=0; 72 sum[p][13]=0;sum[p][14]=0;sum[p][15]=0;sum[p][16]=0; 73 sum[p][17]=0;sum[p][18]=0;sum[p][19]=0;sum[p][20]=0; 74 sum[p][21]=0;sum[p][22]=0;sum[p][23]=0;sum[p][24]=0; 75 sum[p][25]=0;sum[p][26]=0; 76 sum[p][k]=r-l+1; tag[p]=k; 77 return; 78 } 79 int mid=(l+r)>>1; 80 if(tag[p]) { 81 sum[ls[p]][1]=0;sum[ls[p]][2]=0;sum[ls[p]][3]=0;sum[ls[p]][4]=0; 82 sum[ls[p]][5]=0;sum[ls[p]][6]=0;sum[ls[p]][7]=0;sum[ls[p]][8]=0; 83 sum[ls[p]][9]=0;sum[ls[p]][10]=0;sum[ls[p]][11]=0;sum[ls[p]][12]=0; 84 sum[ls[p]][13]=0;sum[ls[p]][14]=0;sum[ls[p]][15]=0;sum[ls[p]][16]=0; 85 sum[ls[p]][17]=0;sum[ls[p]][18]=0;sum[ls[p]][19]=0;sum[ls[p]][20]=0; 86 sum[ls[p]][21]=0;sum[ls[p]][22]=0;sum[ls[p]][23]=0;sum[ls[p]][24]=0; 87 sum[ls[p]][25]=0;sum[ls[p]][26]=0; 88 sum[rs[p]][1]=0;sum[rs[p]][2]=0;sum[rs[p]][3]=0;sum[rs[p]][4]=0; 89 sum[rs[p]][5]=0;sum[rs[p]][6]=0;sum[rs[p]][7]=0;sum[rs[p]][8]=0; 90 sum[rs[p]][9]=0;sum[rs[p]][10]=0;sum[rs[p]][11]=0;sum[rs[p]][12]=0; 91 sum[rs[p]][13]=0;sum[rs[p]][14]=0;sum[rs[p]][15]=0;sum[rs[p]][16]=0; 92 sum[rs[p]][17]=0;sum[rs[p]][18]=0;sum[rs[p]][19]=0;sum[rs[p]][20]=0; 93 sum[rs[p]][21]=0;sum[rs[p]][22]=0;sum[rs[p]][23]=0;sum[rs[p]][24]=0; 94 sum[rs[p]][25]=0;sum[rs[p]][26]=0; 95 sum[ls[p]][tag[p]]=mid-l+1; 96 sum[rs[p]][tag[p]]=r-mid; 97 tag[ls[p]]=tag[rs[p]]=tag[p]; 98 tag[p]=0; 99 } 100 if(qr<=mid) change(ls[p],l,mid,ql,qr,k); 101 else if(ql>mid) change(rs[p],mid+1,r,ql,qr,k); 102 else change(ls[p],l,mid,ql,mid,k),change(rs[p],mid+1,r,mid+1,qr,k); 103 sum[p][1]=sum[ls[p]][1]+sum[rs[p]][1];sum[p][2]=sum[ls[p]][2]+sum[rs[p]][2]; 104 sum[p][3]=sum[ls[p]][3]+sum[rs[p]][3];sum[p][4]=sum[ls[p]][4]+sum[rs[p]][4]; 105 sum[p][5]=sum[ls[p]][5]+sum[rs[p]][5];sum[p][6]=sum[ls[p]][6]+sum[rs[p]][6]; 106 sum[p][7]=sum[ls[p]][7]+sum[rs[p]][7];sum[p][8]=sum[ls[p]][8]+sum[rs[p]][8]; 107 sum[p][9]=sum[ls[p]][9]+sum[rs[p]][9];sum[p][10]=sum[ls[p]][10]+sum[rs[p]][10]; 108 sum[p][11]=sum[ls[p]][11]+sum[rs[p]][11];sum[p][12]=sum[ls[p]][12]+sum[rs[p]][12]; 109 sum[p][13]=sum[ls[p]][13]+sum[rs[p]][13];sum[p][14]=sum[ls[p]][14]+sum[rs[p]][14]; 110 sum[p][15]=sum[ls[p]][15]+sum[rs[p]][15];sum[p][16]=sum[ls[p]][16]+sum[rs[p]][16]; 111 sum[p][17]=sum[ls[p]][17]+sum[rs[p]][17];sum[p][18]=sum[ls[p]][18]+sum[rs[p]][18]; 112 sum[p][19]=sum[ls[p]][19]+sum[rs[p]][19];sum[p][20]=sum[ls[p]][20]+sum[rs[p]][20]; 113 sum[p][21]=sum[ls[p]][21]+sum[rs[p]][21];sum[p][22]=sum[ls[p]][22]+sum[rs[p]][22]; 114 sum[p][23]=sum[ls[p]][23]+sum[rs[p]][23];sum[p][24]=sum[ls[p]][24]+sum[rs[p]][24]; 115 sum[p][25]=sum[ls[p]][25]+sum[rs[p]][25];sum[p][26]=sum[ls[p]][26]+sum[rs[p]][26]; 116 } 117 void print(int p,int l,int r) { 118 if(l==r) { 119 if(sum[p][1]) printf("a"); 120 else if(sum[p][2]) printf("b"); else if(sum[p][3]) printf("c"); 121 else if(sum[p][4]) printf("d"); else if(sum[p][5]) printf("e"); 122 else if(sum[p][6]) printf("f"); else if(sum[p][7]) printf("g"); 123 else if(sum[p][8]) printf("h"); else if(sum[p][9]) printf("i"); 124 else if(sum[p][10]) printf("j"); else if(sum[p][11]) printf("k"); 125 else if(sum[p][12]) printf("l"); else if(sum[p][13]) printf("m"); 126 else if(sum[p][14]) printf("n"); else if(sum[p][15]) printf("o"); 127 else if(sum[p][16]) printf("p"); else if(sum[p][17]) printf("q"); 128 else if(sum[p][18]) printf("r"); else if(sum[p][19]) printf("s"); 129 else if(sum[p][20]) printf("t"); else if(sum[p][21]) printf("u"); 130 else if(sum[p][22]) printf("v"); else if(sum[p][23]) printf("w"); 131 else if(sum[p][24]) printf("x"); else if(sum[p][25]) printf("y"); 132 else if(sum[p][26]) printf("z"); 133 return; 134 } 135 int mid=(l+r)>>1; 136 if(tag[p]) { 137 for(int i=l;i<=r;i++) 138 printf("%c",tag[p]+'a'-1); 139 return ; 140 } 141 print(ls[p],l,mid),print(rs[p],mid+1,r); 142 } 143 inline int R() { 144 int a=0;char c=getchar(); 145 while(c>'9'||c<'0') c=getchar(); 146 while(c>='0'&&c<='9')a=a*10+c-'0',c=getchar(); 147 return a; 148 } 149 inline void read() { 150 char c=getchar(); int pos=0; 151 while(c<'a'||c>'z') c=getchar(); 152 while(c>='a'&&c<='z') s[++pos]=c,c=getchar(); 153 } 154 int main() { 155 n=R();m=R();read(); 156 build(root,1,n); 157 for(register int i=1,o,tl,tr;i<=m;i++) { 158 lst=tl=R();tr=R();o=R(); 159 memset(tmp,0,sizeof(tmp)); 160 ask(root,1,n,tl,tr); 161 if(!o) { 162 for(int j=26;j>=1;j--) 163 if(tmp[j]) { 164 change(root,1,n,lst,lst+tmp[j]-1,j); 165 lst+=tmp[j]; 166 } 167 } else { 168 for(int j=1;j<=26;j++) 169 if(tmp[j]) { 170 change(root,1,n,lst,lst+tmp[j]-1,j); 171 lst+=tmp[j]; 172 } 173 } 174 } 175 print(root,1,n); 176 printf("\n"); 177 return 0; 178 }
T2:matrix
是语文神题(可能是我语文太菜,不像某 sto~CWY~orz)
先说说坑点,每行的 l 到 r 之间不能有 1 !!!
TAT
说说正解吧:
考虑到如果从左向右计算答案左区间的方案可以直接计算,而右区间不好计算,所以设计dp状态:
$f [ i ][ j ]$表示考虑到第 i 列,在开始点在 i 之前的右区间内放了 j 个 1 的方案数
考虑转移:
首先求出两个数组 l 和 r,分别表示左区间的结束点在1到 l 的区间个数和右区间的开始点在 1 到 r 的区间个数
先考虑放在左区间或不放的情况:
对于 $l [ i ] == l [ i - 1 ]$的情况,说明该位置没有新的左区间结束,所以$f [ i ][ j ]=f [ i - 1 ][ j ]$
对于 $l [ i ] != l [ i - 1 ]$的情况,说明该位置有新的左区间结束,所以要乘上安排所有左区间的方案数
总共有 $l [ i ] - l [ i - 1 ]$个左区间需要安排 1 ,之前还空着的列有 $i - j - l [ i - 1 ]$ 个
所以安排左区间的方案数为$P^{l[i]-l[i-1]}_{i-j-l[i-1]}$
所以$f [ i ][ j ]=f [ i - 1 ][ j ]*P^{l[i]-l[i-1]}_{i-j-l[i-1]}$
再考虑放在右区间的情况:
如果$j>0$那么$f[i][j]$可以由$f[i-1][j-1]$转移而来
总共有$r[i]$行,放了$j-1$行,还剩$r[i]-j$行
考虑将新的一个1放在哪一行,并且将方案数乘上新结束的左区间的方案数,得到答案
所以$f [ i ][ j ]+=f [ i - 1 ][ j-1 ]*[r[i]-(j-1)]*P^{l[i]-l[i-1]}_{i-j-l[i-1]}$
这样就转移完了,最终答案为$f[m][n]$,即考虑完m列有n个1放在右区间的方案数
so,code
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<vector> 7 #include<cmath> 8 #define ll long long 9 using namespace std; 10 const int MAXN=4005,D=998244353; 11 int n,m,l[MAXN],r[MAXN]; 12 ll ans,f[MAXN][MAXN],fac[MAXN],inv[MAXN]; 13 ll qpow(ll x,ll k) { 14 ll ret=1; 15 while(k) { 16 if(k&1) ret=ret*x%D; 17 x=x*x%D; 18 k>>=1; 19 } 20 return ret; 21 } 22 void first() { 23 fac[0]=inv[0]=1; 24 for(int i=1;i<=m;i++) fac[i]=fac[i-1]*i%D; 25 inv[m]=qpow(fac[m],D-2); 26 for(int i=m-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%D; 27 } 28 ll A(ll x,ll y) { 29 return fac[x]*inv[x-y]%D; 30 } 31 int main() { 32 scanf("%d%d",&n,&m); 33 for(int i=1,aa,bb;i<=n;i++) { 34 scanf("%d%d",&aa,&bb); 35 ++l[aa];++r[bb]; 36 } 37 first(); 38 for(int i=1;i<=m;i++) l[i]+=l[i-1]; 39 for(int i=1;i<=m;i++) r[i]+=r[i-1]; 40 f[0][0]=1; 41 for(int i=1;i<=m;i++) { 42 for(int j=0;j<=r[i];j++) { 43 if(l[i]==l[i-1]) f[i][j]=f[i-1][j]; 44 else f[i][j]=f[i-1][j]*A(i-j-l[i-1],l[i]-l[i-1])%D; 45 if(j) f[i][j]=(f[i][j]+f[i-1][j-1]*(r[i]-j+1)%D*A(i-j-l[i-1],l[i]-l[i-1])%D)%D; 46 } 47 } 48 printf("%lld\n",(f[m][n]%D+D)%D); 49 return 0; 50 }
T3:big
看错第二问我也是醉了……
首先要理解对手的操作是将你的数字左移一位,并将最高位放到最低位
那么我们容易(?)想到从中间k时刻操作相当于将x和前k位全部操作
所以可以将操作转化为将前k个数操作后再将整个数列异或起来
如果我们枚举所有的k值进行预处理,得到$m+1$个数,记作b数组
那么我们的问题就变为了选择一个数x,使其异或b数组的最小值最大
这就很容易想到用tire树来做了
对于b数组,我们构建一颗01tire树
考虑如何获得最大的答案
我们dfs这颗tire树,对于任意节点p来说:
如果p同时拥有两个儿子,那么无论我们如何构造x,对手一定能将这一位变为0,所以答案这一位为0
如果p只有一个儿子,那么我们一定可以构造出一个x,使答案的这一位为1,所以答案这一位为1
所以一边记录最大值一边统计个数就完了
so,code
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<vector> 7 #include<cmath> 8 using namespace std; 9 const int MAXN=100005; 10 int n,m,a[MAXN],s[MAXN],ans1,ans2,b[MAXN],ch[MAXN*30][2],tot=1,root=1; 11 int calc(int x) { 12 return ((x>>(n-1))+((x&(~(1<<(n-1))))<<1)); 13 } 14 void insert(int x) { 15 int p=root; 16 for(int i=n;i>=1;i--) { 17 if(!ch[p][(x>>(i-1))&1]) ch[p][(x>>(i-1))&1]=++tot; 18 p=ch[p][(x>>(i-1))&1]; 19 } 20 } 21 void dfs(int u,int x,int t) { 22 if(t==0) { 23 if(x>ans1) { 24 ans1=x; 25 ans2=1; 26 } else if(ans1==x) ans2++; 27 return; 28 } 29 if(ch[u][0]&&ch[u][1]) { 30 dfs(ch[u][0],x,t-1); 31 dfs(ch[u][1],x,t-1); 32 } else { 33 if(ch[u][0]) dfs(ch[u][0],(x|(1<<(t-1))),t-1); 34 else dfs(ch[u][1],(x|(1<<(t-1))),t-1); 35 } 36 } 37 int main() { 38 scanf("%d%d",&n,&m); 39 for(int i=1;i<=m;i++) scanf("%d",&a[i]); 40 for(int i=1;i<=m;i++) s[i]=s[i-1]^a[i]; 41 for(int i=0;i<=m;i++) insert(calc(s[i])^(s[m]^s[i])); 42 dfs(root,0,n); 43 printf("%d\n%d\n",ans1,ans2); 44 return 0; 45 }