[关闭]
@happyforever 2018-10-31T11:21:21.000000Z 字数 12674 阅读 544

10.27晚上解题报告

解题报告 清北学堂


各题状况

期望得分:
实际得分:

今天撞题了,所以又加了一道附加题

题目及考场代码

T1

图片.png

  1. /*
  2. */
  3. #include <cstdio>
  4. #include <cstring>
  5. const int N=100005;
  6. char s[N];
  7. int a[N];
  8. /*
  9. void dfs(int now)
  10. {
  11. long long emp=sum[now-1];
  12. for(;s[now] && sum[now]-emp<=x;++now);
  13. // printf("%d ",sum[now]);
  14. if(!s[now])
  15. {
  16. if(sum[now-1]-emp==x)
  17. flag=true;
  18. return ;
  19. }
  20. // puts("");
  21. if(sum[now-1]-emp==x)
  22. dfs(now);
  23. }
  24. */
  25. /*
  26. void bfs(int now)
  27. {
  28. long long emp;
  29. while(true)
  30. {
  31. emp=sum[now-1];
  32. for(;s[now] && sum[now]-emp<=x;++now);
  33. if(!s[now])
  34. {
  35. if(sum[now-1]-emp==x)
  36. flag=true;
  37. return ;
  38. }
  39. if(sum[now-1]-emp!=x)
  40. return ;
  41. }
  42. }
  43. */
  44. int main()
  45. {
  46. freopen("divide.in","r",stdin);
  47. freopen("divide.out","w",stdout);
  48. int T,len;scanf("%d",&T);
  49. while(T--)
  50. {
  51. scanf("%s",s);
  52. len=strlen(s+1);
  53. long long sum=0;
  54. bool flag=false;
  55. for(int i=0;i<len;++i)
  56. a[i+1]=s[i]-'0',sum+=a[i+1];
  57. for(int i=2;i<=len;++i)
  58. {
  59. int tom=0,t=0,p;
  60. if(sum%i==0)
  61. {
  62. p=sum/i;
  63. for(int j=1;j<=len;++j)
  64. {
  65. if(tom+a[j]<p)
  66. {
  67. tom+=a[j];
  68. continue;
  69. }
  70. else
  71. if(tom+a[j]==p)
  72. {
  73. tom=0;
  74. ++t;
  75. continue;
  76. }
  77. else
  78. if(tom+a[j]>p)
  79. break;
  80. }
  81. if(tom==0&&t==i)
  82. {
  83. flag=true;
  84. break;
  85. }
  86. }
  87. }
  88. puts(flag?"YES":"NO");
  89. }
  90. fclose(stdin);fclose(stdout);
  91. return 0;
  92. }

T2

图片.png

  1. #include<cstdio>
  2. int n;
  3. const int ans[]={0,1,1,4,38,728,26704,1866256,251548592,412163774,158488195,768116971,789817415};
  4. int main()
  5. {
  6. freopen("count.in","r",stdin);
  7. freopen("count.out","w",stdout);
  8. scanf("%d",&n);
  9. if(n<=9)
  10. printf("%d",ans[n]);
  11. else printf("baka!\nbzoj 3456 chengshiguihua");
  12. fclose(stdin); fclose(stdout);
  13. return 0;
  14. }

T3

图片.png
图片.png

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. const int M=100005;
  5. long long ans;
  6. int n,m,tot;
  7. int x[M],y[M],c[M],num[M];
  8. int to[M*2],net[M*2],head[M];
  9. int top[M],size[M],dad[M],deep[M],length[M];
  10. inline int read()
  11. {
  12. int n=0,w=1;register char c=getchar();
  13. while(c<'0' || c>'9'){if(c=='-')w=-1;c=getchar();}
  14. while(c>='0' && c<='9')n=n*10+c-'0',c=getchar();
  15. return n*w;
  16. }
  17. void add(int v,int u)
  18. {
  19. to[++tot]=v;net[tot]=head[u];head[u]=tot;//cap[tot]=w;
  20. to[++tot]=u;net[tot]=head[v];head[v]=tot;//cap[tot]=w;
  21. }
  22. inline int max(int x,int y)
  23. {return x>y?x:y;}
  24. void dfs(int now)
  25. {
  26. size[now]=1;
  27. deep[now]=deep[dad[now]]+1;
  28. for(int i=head[now];i;i=net[i])
  29. if(to[i]!=dad[now])
  30. {
  31. dad[to[i]]=now;
  32. length[to[i]]=length[now]+c[to[i]];
  33. dfs(to[i]);
  34. size[now]+=size[to[i]];
  35. }
  36. }
  37. void dfsl(int now)
  38. {
  39. int t=0;
  40. if(!top[now])top[now]=now;
  41. for(int i=head[now];i;i=net[i])
  42. if(to[i]!=dad[now] && size[to[i]]>size[t])
  43. t=to[i];
  44. if(t)
  45. {
  46. top[t]=top[now];
  47. dfsl(t);
  48. }
  49. for(int i=head[now];i;i=net[i])
  50. if(to[i]!=dad[now] && t!=to[i])
  51. dfsl(to[i]);
  52. }
  53. int lca(int x,int y)
  54. {
  55. while(top[x]!=top[y])
  56. {
  57. if(deep[top[x]]<deep[top[y]])
  58. std::swap(x,y);
  59. x=dad[top[x]];
  60. }
  61. return deep[x]>deep[y]?y:x;
  62. }
  63. bool judge(int qwq)
  64. {
  65. for(int i=1;i<=qwq;++i)
  66. for(int j=i+1;j<=qwq;++j)
  67. {
  68. int a=x[i],b=y[i],c=x[j],d=y[j];
  69. int S=lca(a,b);
  70. int T=lca(c,d);
  71. if(deep[S]<deep[T])
  72. {
  73. std::swap(S,T);
  74. std::swap(a,c);
  75. std::swap(b,d);
  76. }
  77. if(lca(S,c)==S||lca(S,d)==S)
  78. return false;
  79. }
  80. return true;
  81. }
  82. void dfsans(int now,int qwq)
  83. {
  84. if(now>m)
  85. {
  86. long long sum=0;
  87. if(qwq==1)
  88. {
  89. int tmp=lca(x[num[1]],y[num[1]]);
  90. sum+=length[x[num[1]]]+length[y[num[1]]]-2*length[tmp]+c[tmp];
  91. ans=max(ans,sum);
  92. }
  93. else
  94. if(qwq>1 && judge(qwq))
  95. {
  96. for(int i=1;i<=qwq;++i)
  97. sum+=length[x[i]]+length[y[i]]-2*length[lca(x[i],y[i])]+c[lca(x[i],y[i])];
  98. ans=max(ans,sum);
  99. }
  100. return ;
  101. }
  102. num[qwq+1]=now;
  103. dfsans(now+1,qwq+1);
  104. num[qwq+1]=0;
  105. dfsans(now+1,qwq);
  106. }
  107. int main()
  108. {
  109. freopen("max.in","r",stdin);
  110. freopen("max.out","w",stdout);
  111. scanf("%d",&n);
  112. for(int i=1;i<=n;++i)
  113. scanf("%d",&c[i]);
  114. for(int i=1;i<n;++i)
  115. add(read(),read());
  116. length[1]=c[1];
  117. dfs(1);dfsl(1);
  118. scanf("%d",&m);
  119. for(int i=1;i<=m;++i)
  120. scanf("%d%d",&x[i],&y[i]);
  121. dfsans(1,0);
  122. printf("%d",ans);
  123. fclose(stdin);fclose(stdout);
  124. return 0;
  125. }

T4

图片.png

  1. /*
  2. */
  3. #include <cstdio>
  4. const int N=33;
  5. int n,m,a[N],b[N],ans;
  6. inline int max(int x,int y)
  7. {return x>y?x:y;}
  8. void dfs(int now,int sum,int tot)
  9. {
  10. if(tot<=m)
  11. ans=max(ans,sum);
  12. if(now>n)return ;
  13. dfs(now+1,sum,tot);
  14. dfs(now+1,sum+b[now],tot^a[now]);
  15. }
  16. int main()
  17. {
  18. freopen("xor.in","r",stdin);
  19. freopen("xor.out","w",stdout);
  20. scanf("%d%d",&n,&m);
  21. for(int i=1;i<=n;++i)
  22. scanf("%d%d",&a[i],&b[i]);
  23. dfs(1,0,0);
  24. printf("%d",ans);
  25. fclose(stdin);fclose(stdout);
  26. return 0;
  27. }

正解及代码

T1

枚举将整个串分成几个部分,而后就可以求出每个部分的总和是多少(也就是划分成的每个部分的“相等”的和是多少),维护前缀和检查和的倍数是否出现。可以开bool数组,查询。

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<string>
  6. #include<cmath>
  7. #include<cstdlib>
  8. #include<ctime>
  9. using namespace std;
  10. typedef long long ll;
  11. typedef long double ld;
  12. typedef pair<int,int> pr;
  13. const double pi=acos(-1);
  14. #define rep(i,a,n) for(int i=a;i<=n;i++)
  15. #define per(i,n,a) for(int i=n;i>=a;i--)
  16. #define Rep(i,u) for(int i=head[u];i;i=Next[i])
  17. #define clr(a) memset(a,0,sizeof a)
  18. #define pb push_back
  19. #define mp make_pair
  20. ld eps=1e-9;
  21. ll pp=1000000007;
  22. ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
  23. ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
  24. ll read(){
  25. ll ans=0;
  26. char last=' ',ch=getchar();
  27. while(ch<'0' || ch>'9')last=ch,ch=getchar();
  28. while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
  29. if(last=='-')ans=-ans;
  30. return ans;
  31. }
  32. //head
  33. #define N 110000
  34. char str[N];
  35. bool a[N*9];
  36. int main(){
  37. freopen("divide.in","r",stdin);
  38. freopen("divide.out","w",stdout);
  39. int T=read();
  40. while(T--){
  41. scanf("%s",str);
  42. int n=strlen(str);
  43. rep(i,0,9*n)a[i]=0;
  44. int t=0;a[t]=1;
  45. rep(i,0,n-1){
  46. t+=str[i]-'0';
  47. a[t]=1;
  48. }
  49. if(t==0){
  50. puts("YES");
  51. continue;
  52. }
  53. bool ans=0;
  54. rep(i,2,n)
  55. if(t%i==0){
  56. int pf=1;
  57. int siz=t/i;
  58. for(int j=siz;j<=t;j+=siz)
  59. if(!a[j]){
  60. pf=0;
  61. break;
  62. }
  63. if(pf){
  64. ans=1;
  65. break;
  66. }
  67. }
  68. if(ans)puts("YES");
  69. else puts("NO");
  70. }
  71. return 0;
  72. }

T2

都可以通过打表解决
的部分分可以选择表示有个点的图的合法的方案数有多少。枚举所在的联通块的大小,找剩余的点,就是一个不合法的情况。总数是

分算法则是。。。
这也就是为啥会有的部分分,最后分纯粹是为了让某些同学装用的

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<cstdlib>
  7. using namespace std;
  8. typedef long long ll;
  9. typedef long double ld;
  10. typedef pair<int,int> pr;
  11. const double pi=acos(-1);
  12. #define rep(i,a,n) for(int i=a;i<=n;i++)
  13. #define per(i,n,a) for(int i=n;i>=a;i--)
  14. #define Rep(i,u) for(int i=head[u];i;i=Next[i])
  15. #define clr(a) memset(a,0,sizeof a)
  16. #define pb push_back
  17. #define mp make_pair
  18. ld eps=1e-9;
  19. ll pp=998244353;
  20. ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
  21. ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
  22. ll read(){
  23. ll ans=0;
  24. char last=' ',ch=getchar();
  25. while(ch<'0' || ch>'9')last=ch,ch=getchar();
  26. while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
  27. if(last=='-')ans=-ans;
  28. return ans;
  29. }
  30. //head
  31. #define N 310000
  32. ll f[N],b1[N],b2[N],inv[N],f2[N],b[N],tt[N],e[N],recf[N],recb[N],Sum[N];
  33. int bel[N];
  34. int n;
  35. ll C(int n,int m){
  36. if(n<m)return 0;
  37. if(m==0 || n==m)return 1;
  38. return b[n]*inv[n-m]%pp*inv[m]%pp;
  39. }
  40. void fnt(ll *a,int n,int fl){
  41. for(int i=n>>1,j=1;j<n;j++){
  42. if(i<j)swap(a[i],a[j]);
  43. int k=n>>1;
  44. for(;k&i;i^=k,k>>=1);
  45. i^=k;
  46. }
  47. ll g=powmod(3,(pp-1)/n,pp);
  48. if(fl==-1)g=powmod(g,n-1,pp);
  49. e[0]=1;
  50. for(int i=1;i<n;i++)e[i]=mo(e[i-1]*g,pp);
  51. for(int m=2,t=n>>1;m<=n;m<<=1,t>>=1)
  52. for(int i=0;i<n;i+=m)
  53. for(int j=i;j<i+(m>>1);j++){
  54. ll u=a[j],v=mo(a[j+(m>>1)]*e[(j-i)*t],pp);
  55. a[j]=u+v;
  56. if(a[j]>=pp)a[j]-=pp;
  57. a[j+(m>>1)]=u-v;
  58. if(a[j+(m>>1)]<0)a[j+(m>>1)]+=pp;
  59. }
  60. }
  61. void Add(ll &a,ll b){
  62. a+=b;
  63. if(a>=pp)a-=pp;
  64. }
  65. int get(){
  66. return (rand()<<10)+rand();
  67. }
  68. int main(){
  69. freopen("count.in","r",stdin);
  70. freopen("count.out","w",stdout);
  71. n=read();
  72. b[0]=inv[0]=1;
  73. rep(i,1,n)b[i]=b[i-1]*i%pp,inv[i]=powmod(b[i],pp-2,pp);
  74. f[1]=f2[1]=1;
  75. rep(i,1,n)b1[i]=powmod(2,C(i,2),pp);
  76. rep(i,1,n)b2[i]=b1[i]*inv[i]%pp;
  77. int nn=256,n2=nn*2;
  78. rep(i,1,n)bel[i]=i/nn;
  79. int num=0;
  80. ll t=powmod(nn*2,pp-2,pp);
  81. rep(i,1,n){
  82. if(i%nn==0){
  83. rep(j,0,nn*2)tt[j]=0;
  84. rep(j,1,bel[i]-1){
  85. int t1=j*n2,t2=(bel[i]-j)*n2;
  86. rep(k,0,nn*2-1)
  87. tt[k]=(tt[k]+recf[t1+k]*recb[t2+k])%pp;
  88. }
  89. fnt(tt,nn*2,-1);
  90. rep(j,0,nn*2-1)Sum[bel[i]*nn+j]=(Sum[bel[i]*nn+j]+tt[j]*t)%pp;
  91. }
  92. f[i]=mo(b1[i]-Sum[i]*b[i-1],pp);
  93. f2[i]=f[i]*inv[i-1]%pp;
  94. for(int j=1;j<i && j<nn;j++)
  95. Sum[i+j]=(Sum[i+j]+f2[j]*b2[i]+f2[i]*b2[j])%pp;
  96. if(i<nn)Add(Sum[i+i],f2[i]*b2[i]%pp);
  97. if(i%nn==nn-1){
  98. rep(j,0,nn*2)tt[j]=0;
  99. rep(j,bel[i]*nn,i)tt[j%nn]=f2[j];
  100. fnt(tt,nn*2,1);
  101. rep(j,0,nn*2-1)recf[bel[i]*n2+j]=tt[j];
  102. rep(j,0,nn*2)tt[j]=0;
  103. rep(j,bel[i]*nn,i)tt[j%nn]=b2[j];
  104. fnt(tt,nn*2,1);
  105. rep(j,0,nn*2-1)recb[bel[i]*n2+j]=tt[j];
  106. }
  107. }
  108. cout<<f[n]<<endl;
  109. return 0;
  110. }

T3

表示以为根的子树里面,答案最大可能是多少(只考虑子树中的路径覆盖子树的情况)
那么有
如果一个树根被覆盖了,就用其他未被覆盖的值加上被覆盖的边的边权。
因为树是随机的,所以深度不会太深。表示节点所有的儿子的值的和减去它本身的值。相当于只要考虑覆盖了根节点的路径的值之和和路径长就可以了
总复杂度就可以是

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<cstdlib>
  7. using namespace std;
  8. typedef long long ll;
  9. typedef long double ld;
  10. typedef pair<int,int> pr;
  11. const double pi=acos(-1);
  12. #define rep(i,a,n) for(int i=a;i<=n;i++)
  13. #define per(i,n,a) for(int i=n;i>=a;i--)
  14. #define Rep(i,u) for(int i=head[u];i;i=Next[i])
  15. #define clr(a) memset(a,0,sizeof a)
  16. #define pb push_back
  17. #define mp make_pair
  18. ld eps=1e-9;
  19. ll pp=1000000007;
  20. ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
  21. ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
  22. ll read(){
  23. ll ans=0;
  24. char last=' ',ch=getchar();
  25. while(ch<'0' || ch>'9')last=ch,ch=getchar();
  26. while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
  27. if(last=='-')ans=-ans;
  28. return ans;
  29. }
  30. //head
  31. #define N 210000
  32. int head[N],v[N],Next[N],dep[N],fa[N][18],a[N],st[N],ed[N];
  33. int n,num,m,num2,num3,nn,head2[N],v2[N],Next2[N];
  34. int lson[N],rson[N],root=0;
  35. ll Sum,f[N],s[N][2],sa[N];
  36. struct node{
  37. int x,y,z;
  38. }q[N];
  39. void add(int x,int y){
  40. v[++num]=y;Next[num]=head[x];head[x]=num;
  41. }
  42. void add2(int x,int y){
  43. v2[++num2]=y;Next2[num2]=head2[x];head2[x]=num2;
  44. }
  45. int Q[N],siz[N];
  46. void dfs(int u){
  47. int t=0,w=1;Q[1]=u;
  48. while(t<w){
  49. u=Q[++t];
  50. sa[u]=sa[fa[u][0]]+a[u];
  51. for(int i=1;(1<<i)<=dep[u];i++)
  52. fa[u][i]=fa[fa[u][i-1]][i-1];
  53. for(int i=head[u];i;i=Next[i])
  54. if(v[i]!=fa[u][0]){
  55. fa[v[i]][0]=u;
  56. dep[v[i]]=dep[u]+1;
  57. Q[++w]=v[i];
  58. }
  59. siz[u]=1;
  60. }
  61. per(i,w,2)siz[fa[Q[i]][0]]+=siz[Q[i]];
  62. st[1]=1;
  63. rep(i,1,n){
  64. u=Q[i];
  65. int t=st[u];ed[u]=st[u]+siz[u]-1;
  66. for(int i=head[u];i;i=Next[i])
  67. if(v[i]!=fa[u][0])st[v[i]]=t+1,t+=siz[v[i]];
  68. }
  69. }
  70. int lca(int x,int y){
  71. if(dep[x]<dep[y])swap(x,y);
  72. per(i,17,0)
  73. if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];
  74. if(x==y)return x;
  75. per(i,17,0)
  76. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  77. return fa[x][0];
  78. }
  79. int lca2(int x,int y){
  80. per(i,17,0)
  81. if(dep[x]-(1<<i)>dep[y])x=fa[x][i];
  82. return x;
  83. }
  84. void change(int &u,int l,int r,int x,int y,ll w,int k){
  85. if(x>r || y<l)return ;
  86. if(!u)u=++num3;
  87. if(x<=l && y>=r){
  88. s[u][k]+=w;
  89. return;
  90. }
  91. int mid=(l+r)>>1;
  92. change(lson[u],l,mid,x,y,w,k);
  93. change(rson[u],mid+1,r,x,y,w,k);
  94. }
  95. ll find(int u,int l,int r,int x,int k){
  96. if(!x)return 0;
  97. if(!u)return 0;
  98. if(l==r)return s[u][k];
  99. int mid=(l+r)>>1;
  100. if(x<=mid)return find(lson[u],l,mid,x,k)+s[u][k];
  101. else return find(rson[u],mid+1,r,x,k)+s[u][k];
  102. }
  103. ll work2(int x,int y){
  104. return find(root,1,n,st[x],1)-find(root,1,n,st[fa[y][0]],1)-(find(root,1,n,st[x],0)-find(root,1,n,st[y],0));
  105. }
  106. ll work(int x,int y,int z){
  107. if(dep[x]<dep[y])swap(x,y);
  108. if(y==z)return work2(x,y)+sa[x]-sa[fa[y][0]];
  109. int t=lca2(y,z);
  110. return work2(x,z)+work2(y,t)-f[t]+sa[x]+sa[y]-sa[z]-sa[fa[z][0]];
  111. }
  112. void dfs2(int u){
  113. per(i,n,1){
  114. u=Q[i];
  115. f[u]=0;
  116. for(int i=head[u];i;i=Next[i])
  117. if(v[i]!=fa[u][0])f[u]+=f[v[i]];
  118. for(int i=head2[u];i;i=Next2[i]){
  119. int t=v2[i];
  120. int x=q[t].x,y=q[t].y,z=q[t].z;
  121. f[u]=max(f[u],work(x,y,z));
  122. }
  123. change(root,1,n,st[u],ed[u],f[u],0);
  124. change(root,1,n,st[fa[u][0]],ed[fa[u][0]],f[u],1);
  125. }
  126. }
  127. int main(){
  128. freopen("max.in","r",stdin);
  129. freopen("max.out","w",stdout);
  130. n=read();
  131. rep(i,1,n)a[i]=read();
  132. rep(i,2,n){
  133. int x=read(),y=read();
  134. add(x,y);add(y,x);
  135. }
  136. dfs(1);
  137. m=read();
  138. rep(i,1,m)q[i].x=read(),q[i].y=read(),q[i].z=lca(q[i].x,q[i].y),add2(q[i].z,i);
  139. dfs2(1);
  140. cout<<f[1]<<endl;
  141. return 0;
  142. }

T4

meet in the middle 左右两边各有种可能。从左右两边各挑选一个,使得其和小于最大。
对所有左边所有的情况建01-trie树,对于右边的找其与左边所有的组合,最优的是多少。
的最高位是的最高位与trie树的某子树的,那这个子树所有组合都是小于的,预处理出所有子树中的最大和,更新答案。

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<cstdlib>
  7. #include<set>
  8. using namespace std;
  9. typedef long long ll;
  10. typedef long double ld;
  11. typedef pair<int,int> pr;
  12. const double pi=acos(-1);
  13. #define rep(i,a,n) for(int i=a;i<=n;++i)
  14. #define per(i,n,a) for(int i=n;i>=a;--i)
  15. #define Rep(i,u) for(int i=head[u];i;i=Next[i])
  16. #define clr(a) memset(a,0,sizeof a)
  17. #define pb push_back
  18. #define mp make_pair
  19. #define fi first
  20. #define sc second
  21. ld eps=1e-9;
  22. ll pp=1000000007;
  23. ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
  24. ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
  25. ll read(){
  26. ll ans=0;
  27. char last=' ',ch=getchar();
  28. while(ch<'0' || ch>'9')last=ch,ch=getchar();
  29. while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
  30. if(last=='-')ans=-ans;
  31. return ans;
  32. }
  33. //head
  34. int nn=1,ans=0,n,m,tot=0;
  35. int son[2000000][2],Max[2000000];
  36. int a[50],b[50];
  37. void insert(int x,int s){
  38. int t=1;
  39. per(i,29,0){
  40. int kk=(x>>i)&1;
  41. if(!son[t][kk])son[t][kk]=++nn;
  42. t=son[t][kk];
  43. Max[t]=max(Max[t],s);
  44. }
  45. }
  46. void query(int u,int dep,int x,int s){
  47. if(!u)return;
  48. if(dep==-1)return;
  49. int kk=((x>>dep)&1)^((m>>dep)&1);
  50. if(((m>>dep)&1)==1)ans=max(ans,s+Max[son[u][kk^1]]);
  51. query(son[u][kk],dep-1,x,s);
  52. }
  53. void dfs1(int t1,int t2,int x,int s){
  54. if(t1>t2){
  55. tot+=1;
  56. insert(x,s);
  57. return;
  58. }
  59. dfs1(t1+1,t2,x,s);
  60. dfs1(t1+1,t2,x^a[t1],s+b[t1]);
  61. }
  62. void dfs2(int t1,int t2,int x,int s){
  63. if(t1>t2){
  64. query(1,29,x,s);
  65. return;
  66. }
  67. dfs2(t1+1,t2,x,s);
  68. dfs2(t1+1,t2,x^a[t1],s+b[t1]);
  69. }
  70. int main(){
  71. freopen("xor.in","r",stdin);
  72. freopen("xor.out","w",stdout);
  73. n=read();m=read();m+=1;
  74. int ss=0;
  75. rep(i,1,n)a[i]=read(),b[i]=read(),ss+=b[i];
  76. dfs1(1,n/2,0,0);
  77. dfs2(n/2+1,n,0,0);
  78. cout<<ans<<endl;
  79. return 0;
  80. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注