A. XOR

求出所有数的异或和$sum$,将所有数and上$sum$,然后求线性基,则选取$sum$的所有$1$对应的基最优。

时间复杂度$O(n\log x)$。

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<algorithm>
  4. #include<ctime>
  5. using namespace std;
  6. typedef long long ll;
  7. int Case,n,i,j;ll ans,sum,A,B,a[100],x,v[111111],pool[100];
  8. const int N=20;
  9. ll cal(){
  10. ll ans=sum;
  11. for(int S=0;S<1<<n;S++){
  12. ll A=sum,B=0;
  13. for(i=0;i<n;i++)if(S>>i&1)A^=v[i],B^=v[i];
  14. A-=B;
  15. if(A<0)A=-A;
  16. if(A<ans)ans=A;
  17. }
  18. return ans;
  19. }
  20. void print(ll x){
  21. for(int i=11;~i;i--)printf("%lld",x>>i&1);
  22. puts("");
  23. }
  24. ll myabs(ll x){return x>0?x:-x;}
  25. ll solve1(int x){
  26. ll cur=a[x];
  27. for(int i=x-1;~i;i--)if(sum>>i&1){
  28. cur^=a[i];
  29. }
  30. return myabs(cur-(sum^cur));
  31. }
  32. ll solve2(int x){
  33. ll cur=0;
  34. for(int i=x-1;~i;i--){
  35. cur=max(cur,cur^a[i]);
  36. }
  37. return myabs(cur-(sum^cur));
  38. }
  39. int main(){
  40. //srand(time(NULL));
  41. scanf("%d",&Case);
  42. while(Case--){
  43. scanf("%d",&n);
  44. //n=rand()%10+1;
  45. sum=0;
  46. for(i=0;i<61;i++)a[i]=0;
  47. for(i=0;i<n;i++){
  48. scanf("%lld",&x);
  49. //x=rand()%1000;
  50. v[i]=x;
  51. sum^=x;
  52. for(j=60;~j;j--)if(x>>j&1){
  53. if(a[j])x^=a[j];
  54. else {a[j]=x;break;}
  55. }
  56. }
  57.  
  58. //ll vio=cal();
  59.  
  60. for(i=0;i<61;i++)for(j=i+1;j<61;j++)if(a[j]>>i&1)a[j]^=a[i];
  61.  
  62. for(i=60;~i;i--)if(sum>>i&1)break;
  63. int lim=i;
  64. if(lim>=0){
  65. for(i=0;i<61;i++)pool[i]=a[i]&sum,a[i]=0;
  66. for(i=0;i<61;i++){
  67. x=pool[i];
  68. for(j=60;~j;j--)if(x>>j&1){
  69. if(a[j])x^=a[j];
  70. else {a[j]=x;break;}
  71. }
  72. }
  73. for(i=0;i<61;i++)for(j=i+1;j<61;j++)if(a[j]>>i&1)a[j]^=a[i];
  74. ans=min(sum,min(solve1(lim),solve2(lim)));
  75. }else{
  76. ans=0;
  77. }
  78.  
  79. /*A=sum,B=0;*/
  80.  
  81. //print(sum);
  82. //for(i=60;~i;i--)if(a[i])print(a[i]);
  83.  
  84. /*ans=sum;
  85. for(i=60;~i;i--)if((A^a[i])>=(B^a[i])&&(A^a[i])-(B^a[i])<ans){
  86. A^=a[i];
  87. B^=a[i];
  88. ans=A-B;
  89. }*/
  90. /*if(ans==vio)puts("OK");else{
  91. printf("vio=%lld ans=%lld\n",vio,ans);
  92. printf("%d\n",n);
  93. for(i=0;i<n;i++)printf("%lld ",v[i]);
  94. puts("");
  95. while(1);
  96. }*/
  97. printf("%lld\n",ans);
  98. }
  99. }

  

B. Tribute

按题意模拟即可。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int casenum, casei;
  4. typedef unsigned int UI;
  5. int n;
  6. vector<UI>vt, wt;
  7. multiset<UI>sot;
  8. multiset<UI>ans;
  9. bool solve()
  10. {
  11. for(int i = 1; i <= n; ++i)
  12. {
  13. int x = *sot.begin();
  14. ans.insert(x);
  15. // printf("x = %d\n", x);
  16. // for(auto y : vt)printf("%d ", y); puts("");
  17. wt.clear();
  18. for(auto y : vt)
  19. {
  20. int z = x + y;
  21. // printf("%d\n", z);
  22. if(sot.find(z) == sot.end())return 0;
  23. sot.erase(sot.find(z));
  24. wt.push_back(z);
  25. }
  26. for(auto y : wt)vt.push_back(y);
  27. }
  28. return 1;
  29. }
  30. int main()
  31. {
  32. scanf("%d", &casenum);
  33. for(casei = 1; casei <= casenum; casei ++)
  34. {
  35. scanf("%d", &n);
  36. int m = (1 << n) - 1;
  37. vt.clear(); vt.push_back(0);
  38. sot.clear();
  39. ans.clear();
  40. for(int i = 1; i <= m; ++i)
  41. {
  42. int x; scanf("%d", &x);
  43. sot.insert(x);
  44. }
  45. if(!solve())puts("NO");
  46. else
  47. {
  48. int id = 0;
  49. for(auto it : ans)printf("%d%c", it, ++id == n ? '\n' : ' ');
  50. }
  51. }
  52. }

  

C. Boardroom Meeting

CDQ分治+扫描线树状数组,时间复杂度$O(n\log^2n)$。

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. const int N=200010;
  5. int Case,n,i,a[N],b[N],c[N],ans,f[N],qa[N],qb[N],bit[N],vis[N],T;
  6. inline void up(int&a,int b){a<b?(a=b):0;}
  7. inline void ins(int x,int p){for(;x<=n;x+=x&-x)if(vis[x]<T)vis[x]=T,bit[x]=p;else up(bit[x],p);}
  8. inline void ask(int x,int&p){for(;x;x-=x&-x)if(vis[x]==T)up(p,bit[x]);}
  9. inline bool cmp(int x,int y){return a[x]<a[y];}
  10. void solve(int l,int r){
  11. if(l==r){
  12. up(ans,++f[l]);
  13. return;
  14. }
  15. int mid=(l+r)>>1,i,j,ca=0,cb=0;
  16. solve(l,mid);
  17. for(i=l;i<=mid;i++)qa[++ca]=i;
  18. for(;i<=r;i++)qb[++cb]=i;
  19. sort(qa+1,qa+ca+1,cmp);
  20. sort(qb+1,qb+cb+1,cmp);
  21. T++;
  22. for(i=j=1;i<=cb;i++){
  23. while(j<=ca&&a[qa[j]]<a[qb[i]]){
  24. ins(b[qa[j]],f[qa[j]]);
  25. j++;
  26. }
  27. ask(b[qb[i]]-1,f[qb[i]]);
  28. }
  29. solve(mid+1,r);
  30. }
  31. int main(){
  32. scanf("%d",&Case);
  33. while(Case--){
  34. scanf("%d",&n);
  35. for(i=1;i<=n;i++)scanf("%d",&a[i]);
  36. for(i=1;i<=n;i++)scanf("%d",&b[i]),c[i]=b[i];
  37. sort(c+1,c+n+1);
  38. for(i=1;i<=n;i++)b[i]=lower_bound(c+1,c+n+1,b[i])-c;
  39. for(i=1;i<=n;i++)f[i]=0;
  40. ans=0;
  41. solve(1,n);
  42. printf("%d\n",ans);
  43. }
  44. }
  45. /*
  46. 1
  47. 6
  48. 1 2 6 3 4 6
  49. 4 1 3 5 7 7
  50. */

  

D. Secret Santa

第二类斯特林数容斥,时间复杂度$O(a\log n)$。

  1. #include<cstdio>
  2. const int N=2010,P=1000000007;
  3. int n,a,i,j,Case,fac[N],S[N][N];
  4. int po(int a,int b){int t=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;return t;}
  5. int T(int m,int n){
  6. int ans=0;
  7. for(int k=0;k<m;k++){
  8. int t=fac[k];
  9. if((k+m)%2)t=(P-t)%P;
  10. t=1LL*t*po(k+1,n)%P;
  11. t=1LL*t*S[m][k+2]%P;
  12. ans=(ans+t)%P;
  13. }
  14. return ans;
  15. }
  16. int main(){
  17. for(i=0;i<N;i++)for(j=0;j<N;j++){
  18. if(i>=1&&j==0){S[i][j]=0;continue;}
  19. if(i==j){S[i][j]=1;continue;}
  20. if(j>=1&&j<i)S[i][j]=(1LL*S[i-1][j]*j+S[i-1][j-1])%P;
  21. }
  22. for(fac[0]=i=1;i<N;i++)fac[i]=1LL*fac[i-1]*i%P;
  23. scanf("%d",&Case);
  24. while(Case--){
  25. scanf("%d%d",&n,&a);a++;n-=a-2;
  26. printf("%d\n",T(a,n));
  27. }
  28. }

  

E. Guessing Game

状压DP,设$f[S]$表示$S$情况下最优策略最坏需要的步数,其中$S$是个$k$位$3$进制数,分别表示每一位未询问、已询问且回答为$0$、已询问且回答为$1$的情况。

用高维前缀和预处理出所有$f[S]=0$的状态,剩下的状态枚举询问哪一位转移即可。

时间复杂度$O(3^kk)$。

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. const int N=13,M=1600000;
  5. int p[20],Case,n,m,i,j,k,f[M],c[M];char s[20];
  6. inline int get(int x,int y){return x/p[y]%3;}
  7. int main(){
  8. for(p[0]=i=1;i<20;i++)p[i]=p[i-1]*3;
  9. scanf("%d",&Case);
  10. while(Case--){
  11. scanf("%d%d",&n,&k);
  12. m=p[k];
  13. for(i=0;i<m;i++)c[i]=0;
  14. for(i=1;i<=n;i++){
  15. scanf("%s",s);
  16. int t=0;
  17. for(j=0;j<k;j++)t=t*3+s[j]-'0';
  18. c[t]++;
  19. }
  20. for(i=0;i<k;i++)for(j=0;j<m;j++)if(get(j,i)==2){
  21. c[j]+=c[j-p[i]]+c[j-p[i]*2];
  22. }
  23. for(i=0;i<m;i++){
  24. if(c[i]<=1){f[i]=0;continue;}
  25. f[i]=M;
  26. for(j=0;j<k;j++)if(get(i,j)==2){
  27. f[i]=min(f[i],max(f[i-p[j]],f[i-p[j]*2]));
  28. }
  29. f[i]++;
  30. }
  31. printf("%d\n",f[m-1]);
  32. }
  33. }

  

F. Flat Earth

按题意模拟即可。

  1. #include<stdio.h>
  2. #include<math.h>
  3.  
  4. int casenum, casei, a[10];
  5. const double PI = acos(-1.0);
  6.  
  7. int main()
  8. {
  9. scanf("%d", &casenum);
  10. for(casei = 1; casei <= casenum; casei ++){
  11. for(int i = 1; i <= 8; i ++){
  12. scanf("%d", &a[i]);
  13. }
  14. printf("%.10f\n", PI * a[4] * a[4]);
  15. }
  16. }

  

G. We Need More Managers!

建立一张$2^n$个点的图,分别表示每种串。对于每个点,向恰好改变了一位的$n$个点连边。

则题意可转化为对给定$m$个点求出两两最短路作为权值的最小生成树。

设$p_x$和$d_x$分别表示离每个点最近的给定串以及对应的距离,可以BFS求出,则对于一条边$(u,v)$,在生成树中加入一条连接$p_u$和$p_v$,权值为$d_u+d_v+1$的边即可。

时间复杂度$O(n2^n\alpha(m))$。

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. const int N=1100000;
  5. int Case,n,m,all,i,j,a[N];char s[100];
  6. int h,t,d[N],p[N],x,y,z,q[N];
  7. int f[N],ans,ce;
  8. struct E{
  9. int x,y,z;
  10. E(){}
  11. E(int _x,int _y,int _z){x=_x,y=_y,z=_z;}
  12. }e[N*20];
  13. inline bool cmp(const E&a,const E&b){return a.z<b.z;}
  14. inline void ext(int x,int y,int z){
  15. if(y<d[x]){
  16. d[x]=y;
  17. p[x]=z;
  18. q[++t]=x;
  19. }
  20. }
  21. int F(int x){return f[x]==x?x:f[x]=F(f[x]);}
  22. inline void add(int x,int y,int z){
  23. if(x!=y)e[++ce]=E(x,y,z);
  24. }
  25. int main(){
  26. scanf("%d",&Case);
  27. while(Case--){
  28. scanf("%d%d",&n,&m);
  29. all=1<<n;
  30. for(i=0;i<all;i++)d[i]=N;
  31. for(i=1;i<=m;i++){
  32. scanf("%s",s);
  33. a[i]=0;
  34. for(j=0;j<n;j++)a[i]=a[i]*2+(s[j]=='L');
  35. d[a[i]]=0,p[a[i]]=i;
  36. }
  37. h=1,t=0;
  38. for(i=0;i<all;i++)if(!d[i])q[++t]=i;
  39. while(h<=t){
  40. x=q[h++];
  41. y=d[x]+1;
  42. z=p[x];
  43. for(i=0;i<n;i++)ext(x^(1<<i),y,z);
  44. }
  45. ce=0;
  46. for(i=0;i<all;i++)for(j=0;j<n;j++)add(p[i],p[i^(1<<j)],d[i]+d[i^(1<<j)]+1);
  47. for(i=1;i<=m;i++)f[i]=i;
  48. ans=0;
  49. sort(e+1,e+ce+1,cmp);
  50. for(i=1;i<=ce;i++)if(F(e[i].x)!=F(e[i].y))f[f[e[i].x]]=f[e[i].y],ans+=e[i].z;
  51. printf("%d\n",ans);
  52. }
  53. }

  

H. Masterpiece

若不考虑每个点是被第几次走过的,则方案唯一,$O(n)$模拟求出方案后统计分岔点个数$t$,则答案为$2^t$。

  1. #include<stdio.h>
  2. #include<iostream>
  3. #include<string.h>
  4. #include<string>
  5. #include<ctype.h>
  6. #include<math.h>
  7. #include<set>
  8. #include<map>
  9. #include<vector>
  10. #include<queue>
  11. #include<bitset>
  12. #include<algorithm>
  13. #include<time.h>
  14. using namespace std;
  15. void fre() { }
  16. #define MS(x, y) memset(x, y, sizeof(x))
  17. #define rt 1,1,n
  18. #define ls o<<1
  19. #define rs o<<1|1
  20. #define mid (l+r>>1)
  21. #define lson ls,l,mid
  22. #define rson rs,mid+1,r
  23. typedef long long LL;
  24. typedef unsigned long long UL;
  25. typedef unsigned int UI;
  26. template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
  27. template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
  28. const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
  29. template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
  30. int casenum, casei;
  31. int n;
  32. int r[N], c[N];
  33. //try go to (y, x)
  34. bool flag = 1;
  35. int r1, r2;
  36. int c1, c2;
  37. bool doit(int y, int x)
  38. {
  39. if(r1 == r2 && c1 == c2)return flag = 1;
  40. if(y > n || x > n)return 0;
  41. if(!r[y] || ! c[x])return 0;
  42. --r[y];
  43. --c[x];
  44. return flag = 1;
  45. }
  46. int solve()
  47. {
  48. int ans = 1;
  49. r1 = 1, c1 = 1;
  50. r2 = 1, c2 = 1;
  51. doit(1, 1); --r[1]; --c[1];
  52. while(1)
  53. {
  54. flag = 0;
  55. if(r1 == r2 && c1 == c2)
  56. {
  57. if(r1 == n && c1 == n)
  58. {
  59. return ans;
  60. }
  61. int rnum = r[r1];
  62. int cnum = c[c1];
  63. if(rnum && cnum)
  64. {
  65. ans = ans * 2 % Z;
  66. for(int i = 1; i <= rnum; ++i)
  67. {
  68. if(!doit(r1, ++c1))return 0;
  69. }
  70. for(int i = 1; i <= cnum; ++i)
  71. {
  72. if(!doit(++r2, c2))return 0;
  73. }
  74. }
  75. else if(rnum)
  76. {
  77. if(!doit(r1, ++c1))return 0;
  78. ++c2;
  79. }
  80. else if(cnum)
  81. {
  82. if(!doit(++r1, c1))return 0;
  83. ++r2;
  84. }
  85. else return 0;
  86. }
  87. while(r1 < r2)
  88. {
  89. if(r[r1])
  90. {
  91. if(!doit(r1, ++c1))return 0;
  92. }
  93. else
  94. if(!doit(++r1, c1))return 0;
  95. }
  96. while(r2 < r1)
  97. {
  98. if(r[r2])
  99. {
  100. if(!doit(r2, ++c2))return 0;
  101. }
  102. else
  103. if(!doit(++r2, c2))return 0;
  104. }
  105. while(c1 < c2)
  106. {
  107. if(c[c1])
  108. {
  109. if(!doit(++r1, c1))return 0;
  110. }
  111. else
  112. if(!doit(r1, ++c1))return 0;
  113. }
  114. while(c2 < c1)
  115. {
  116. if(c[c2])
  117. {
  118. if(!doit(++r2, c2))return 0;
  119. }
  120. else
  121. if(!doit(r2, ++c2))return 0;
  122. }
  123. if(!flag)return 0;
  124. }
  125. }
  126. int main()
  127. {
  128. scanf("%d", &casenum);
  129. for(casei = 1; casei <= casenum; ++casei)
  130. {
  131. scanf("%d", &n);
  132. //int n = rand() % 10 + 1;
  133. for(int i = 1; i <= n; ++i)
  134. {
  135. scanf("%d", &r[i]);
  136. //r[i] = rand() % (n + 1);
  137. }
  138. for(int i = 1; i <= n; ++i)
  139. {
  140. scanf("%d", &c[i]);
  141. //c[i] = rand() % (n + 1);
  142. }
  143. int ans = solve();
  144. for(int i = 1; i <= n; ++i)
  145. {
  146. if(r[i] || c[i])ans = 0;
  147. }
  148. printf("%d\n", ans);
  149. }
  150. return 0;
  151. }
  152.  
  153. /*
  154. 【trick&&吐槽】
  155.  
  156. 【题意】
  157.  
  158. 【分析】
  159.  
  160. 【时间复杂度&&优化】
  161.  
  162. 100
  163. 5
  164. 3 3 3 3 3
  165. 1 4 4 3 3
  166.  
  167. 4
  168. 4 2 2 4
  169. 4 2 2 4
  170.  
  171. */

  

I. Don’t Split The Atom!

胜负只取决于$n$的奇偶性。

  1. #include<stdio.h>
  2. #include<math.h>
  3.  
  4. int casenum, casei, a[10];
  5. const double PI = acos(-1.0);
  6.  
  7. int main()
  8. {
  9. scanf("%d", &casenum);
  10. for(casei = 1; casei <= casenum; casei ++){
  11. int n;
  12. scanf("%d", &n);
  13. puts(n & 1 ? "B" : "A");
  14. }
  15. }

  

J. Bobby Tables

组合数可以看作长度为$k$的一个区间除以长度为$k$的一个前缀。

枚举每个$k$作为前缀,二分对应的区间,取对数加速判定,在附近配合取模判定即可。

时间复杂度$O(m\log m)$。

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<algorithm>
  4. using namespace std;
  5. typedef long double ld;
  6. const int N=200010,P=1000000007,K=20;
  7. const ld eps=1e-2;
  8. int Case,n,m,i,a[N],fac[N],inv[N],mul;
  9. ld Log[N],s[N],sum;
  10. inline bool check(int n,int m){
  11. ld A=s[n]-s[n-m]-s[m];
  12. if(fabs(A-sum)>eps)return 0;
  13. int B=1LL*fac[n]*inv[n-m]%P*inv[m]%P;
  14. if(B!=mul)return 0;
  15. puts("YES");
  16. printf("%d %d\n",n,m);
  17. return 1;
  18. }
  19. inline void solve(){
  20. scanf("%d%d",&n,&m);
  21. sum=0;
  22. mul=1;
  23. for(i=1;i<=n;i++){
  24. scanf("%d",&a[i]);
  25. mul=1LL*mul*a[i]%P;
  26. sum+=Log[a[i]];
  27. }
  28. for(i=1;i<=m;i++){
  29. //[x,x+i-1]/[1..i]
  30. //C(x+i-1,i)
  31. //x+i-1>=i
  32. //1<=x<=m+1-i
  33. //x+i-1<=m
  34. int l=1,r=m+1-i;
  35. while(l<=r){
  36. int mid=(l+r)>>1;
  37. ld A=s[mid+i-1]-s[mid-1]-s[i];
  38. if(fabs(A-sum)<eps){
  39. for(int j=max(mid-K,1);j<=min(m+1-i,mid+K);j++)if(check(j+i-1,i))return;
  40. break;
  41. }
  42. if(A<sum)l=mid+1;else r=mid-1;
  43. }
  44. }
  45. puts("NO");
  46. }
  47. int main(){
  48. for(i=1;i<N;i++)Log[i]=log2(i);
  49. for(i=1;i<N;i++)s[i]=s[i-1]+Log[i];
  50. for(inv[0]=inv[1]=1,i=2;i<N;i++)inv[i]=1LL*(P-inv[P%i])*(P/i)%P;
  51. for(fac[0]=i=1;i<N;i++)fac[i]=1LL*fac[i-1]*i%P;
  52. for(i=1;i<N;i++)inv[i]=1LL*inv[i-1]*inv[i]%P;
  53. scanf("%d",&Case);
  54. while(Case--){
  55. solve();
  56. }
  57. }

  

K. Triples

长链剖分或树分治经典题。

  1. #include<cstdio>
  2. #include<vector>
  3. #include<algorithm>
  4. #include<cstring>
  5. #define pb push_back
  6. #define V vector
  7. #define N 200010
  8. using namespace std;
  9. typedef long long ll;
  10. typedef pair<int,ll>P;
  11. int Case;
  12. int n,i,x,y,g[N],v[N<<1],nxt[N<<1],ed,f[N],del[N];ll ans;V<P>h[N];
  13. inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
  14. inline bool cmp(V<int>*a,V<int>*b){return a->size()>b->size();}
  15. template<class C>inline C&get(V<C>&a,size_t x){return a[a.size()-x-1];}
  16. V<int>*dfs(int x,int y){
  17. V<V<int>*>t;
  18. for(int i=g[x];i;i=nxt[i])if(v[i]!=y)t.pb(dfs(v[i],x));
  19. if(!t.size())return new V<int>(1,1);
  20. sort(t.begin(),t.end(),cmp);
  21. V<int>*a=t[0];
  22. a->pb(1);
  23. if(t.size()==1)return a;
  24. V<ll>b;
  25. b.resize(t[1]->size()+1,0);
  26. for(int i=1;i<t.size();i++){
  27. V<int>*u=t[i];
  28. for(int j=1;j<=u->size();j++){
  29. int ch=get(*u,j-1),&rt=get(*a,j);ll&rd=get(b,j);
  30. ans+=1LL*ch*rd;
  31. rd+=1LL*ch*rt;
  32. rt+=ch;
  33. }
  34. }
  35. for(int i=1;i<b.size();i++){
  36. h[x].pb(P(i,get(b,i)));
  37. ans-=1LL*get(b,i)*get(*a,i);
  38. }
  39. return a;
  40. }
  41. void cal(int x,int y){
  42. f[x]=1;
  43. for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&!del[v[i]])cal(v[i],x),f[x]+=f[v[i]];
  44. }
  45. inline int findroot(int x){
  46. cal(x,-1);
  47. int n=f[x],t=0,y=-1;
  48. do{
  49. t=0;
  50. for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&!del[v[i]]&&2*f[v[i]]>n){
  51. y=x,x=v[i],t=1;
  52. break;
  53. }
  54. }while(t);
  55. return x;
  56. }
  57. inline void work(V<V<int> >&d,V<V<P> >&q,int k,bool rt,int x){
  58. int st=k==1?0:d.size()-1,en=k==1?d.size():-1;V<int>a(1,rt);
  59. for(int i=st;i!=en;i+=k){
  60. V<int>D=d[i];
  61. for(V<P>::iterator p=q[i].begin();p!=q[i].end();p++){
  62. int j=p->first;
  63. if(j<a.size())ans+=1LL*a[j]*p->second;
  64. }
  65. a.resize(max(a.size(),D.size()),0);
  66. for(int j=0;j<D.size();j++)a[j]+=D[j];
  67. }
  68. if(rt)for(V<P>::iterator p=h[x].begin();p<h[x].end();p++){
  69. int j=p->first;
  70. if(j<a.size())ans+=1LL*a[j]*p->second;
  71. }
  72. }
  73. void dfsd(int x,int y,int z,V<int>&d){
  74. if(z==d.size())d.pb(1);else d[z]++;
  75. for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&!del[v[i]])dfsd(v[i],x,z+1,d);
  76. }
  77. void dfsq(int x,int y,int z,V<P>&q){
  78. for(V<P>::iterator i=h[x].begin();i<h[x].end();i++){
  79. int t=i->first-z;
  80. if(t>=0)q.pb(P(t,i->second));
  81. }
  82. for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&!del[v[i]])dfsq(v[i],x,z+1,q);
  83. }
  84. void solve(int x){
  85. int y=findroot(x);
  86. del[y]=1;
  87. for(int i=g[y];i;i=nxt[i])if(!del[v[i]])solve(v[i]);
  88. V<V<int> >d;V<V<P> >q;
  89. for(int i=g[y];i;i=nxt[i])if(!del[v[i]]){
  90. V<int>A(1,0);
  91. dfsd(v[i],-1,1,A);
  92. d.pb(A);
  93. V<P>B;
  94. dfsq(v[i],-1,1,B);
  95. q.pb(B);
  96. }
  97. work(d,q,1,1,y),work(d,q,-1,0,y);
  98. del[y]=0;
  99. }
  100. int main(){
  101. scanf("%d",&Case);
  102. while(Case--){
  103. i=x=y=0;
  104. memset(g,0,sizeof g);
  105. memset(f,0,sizeof f);
  106. memset(v,0,sizeof v);
  107. memset(nxt,0,sizeof nxt);
  108. ed=0;
  109. memset(del,0,sizeof del);
  110. ans=0;
  111. for(i=0;i<N;i++)h[i].clear();
  112. scanf("%d",&n);
  113. for(i=1;i<n;i++){
  114. scanf("%d%d",&x,&y);
  115. x--,y--;
  116. add(x,y),add(y,x);
  117. }
  118. dfs(0,-1);
  119. solve(0);
  120. printf("%lld\n",ans);
  121. }
  122. }

  

L. Related Languages

枚举$O(nm)$对区间右端点,左端点的取值满足单调性,双指针即可。

时间复杂度$O(nm)$。

  1. #include<cstdio>
  2. const int N=4010;
  3. int Case,n,m,i,j,k,ans,g[N*3];
  4. char a[N],b[N],f[N][N];
  5. int w[N*3],V;
  6. int main(){
  7. scanf("%d",&Case);
  8. while(Case--){
  9. scanf("%d%d%d%s%s",&n,&m,&V,a+1,b+1);
  10. ans=0;
  11. for(i=1;i<=n;i++)for(j=1;j<=m;j++)f[i][j]=a[i]!=b[j];
  12. for(i=0;i<=N+N+5;i++)g[i]=w[i]=0;
  13. for(i=1;i<=n;i++)for(j=1;j<=m;j++){
  14. k=i-j+N;
  15. g[k]++;
  16. w[k]+=f[i][j];
  17. int G=g[k],W=w[k];
  18. while(G>0&&W>V){
  19. G--;
  20. W-=f[i-G][j-G];
  21. }
  22. g[k]=G;
  23. w[k]=W;
  24. if(G>ans)ans=G;
  25. }
  26. printf("%d\n",ans);
  27. }
  28. }

  

Petrozavodsk Winter-2018. Jagiellonian U Contest的更多相关文章

  1. Petrozavodsk Winter Training Camp 2018 Jagiellonian U Contest Problem A. XOR

    先把所有的数异或起来 得到sum 然后sum有一些位是1一些位是0 是0的位表示所有数里面有这位的数是偶数个 则无论怎么划分数 这一位对最终的答案都是不会有贡献的  因为偶数=偶数+偶数/奇数+奇数 ...

  2. 2015 UESTC Winter Training #7【2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest】

    2015 UESTC Winter Training #7 2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest 据 ...

  3. 2015-2016 Petrozavodsk Winter Training Camp, Nizhny Novgorod SU Contest (5/9)

    2015-2016 Petrozavodsk Winter Training Camp, Nizhny Novgorod SU Contest B. Forcefield 题意 给你一维平面上n个镜子 ...

  4. Petrozavodsk Winter Training Camp 2018

    Petrozavodsk Winter Training Camp 2018 Problem A. Mines 题目描述:有\(n\)个炸弹放在\(x\)轴上,第\(i\)个位置为\(p_i\),爆炸 ...

  5. 2014-2015 Petrozavodsk Winter Training Camp, Contest.58 (Makoto rng_58 Soejima contest)

    2014-2015 Petrozavodsk Winter Training Camp, Contest.58 (Makoto rng_58 Soejima contest) Problem A. M ...

  6. 2018 Multi-University Training Contest 2

    题目链接:2018 Multi-University Training Contest 2 6318 Swaps and Inversions 题意:sum=x*逆序个数+交换次数*y,使sum最小 ...

  7. 2018 Multi-University Training Contest 1

    比赛链接:2018 Multi-University Training Contest 1 6301 Distinct Values 题意:输出一个长度为n的序列,要求满足m个区间的数都不相同,并且字 ...

  8. 【二分+拓扑排序】Milking Order @USACO 2018 US Open Contest, Gold/upc_exam_6348

    目录 Milking Order @USACO 2018 US Open Contest, Gold/upc_exam_6348 PROBLEM 题目描述 输入 输出 样例输入 样例输出 提示 MEA ...

  9. 2018 AICCSA Programming Contest

    2018 AICCSA Programming Contest A Tree Game B Rectangles 思路:如果存在大于0的交面积的话, 那么肯定能找到一条水平的直线 和 一条垂直的直线, ...

  10. hdu 6301 Distinct Values (2018 Multi-University Training Contest 1 1004)

    Distinct Values Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

随机推荐

  1. CNN:Channel与Core的高H、宽W的权值理解

    转自: 知乎问题[能否对卷积神经网络工作原理做一个直观的解释?https://www.zhihu.com/question/39022858]中YJango 的回答; 因总是忘记回答地址,方便以后查阅 ...

  2. Dubbo2.6.5入门——简单的HelloWorld

    建立父工程 打开idea,新建一个空的maven工程,作为整个项目的父工程. <?xml version="1.0" encoding="UTF-8"?& ...

  3. JAVA WEB开发环境与搭建

    一:jdk下载与安装 (1)官网下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-506665 ...

  4. (二叉树 递归) leetcode 144. Binary Tree Preorder Traversal

    Given a binary tree, return the preorder traversal of its nodes' values. Example: Input: [1,null,2,3 ...

  5. CVE-2017-7494 Linux Samba named pipe file Open Vul Lead to DLL Execution

    catalogue . 漏洞复现 . 漏洞代码原理分析 . 漏洞利用前提 . 临时缓解 && 修复手段 1. 漏洞复现 . SMB登录上去 . 枚举共享目录,得到共享目录/文件列表,匿 ...

  6. An Apple a day keeps the doctor away

    An apple a day keeps the doctor away. 一天一苹果,不用请医生. 活学活用:apple as like as an apple to an oyster 毫无相同之 ...

  7. Groovy 设计模式 -- 保镖模式

    Bouncer Pattern http://groovy-lang.org/design-patterns.html#_bouncer_pattern 保镖模式主要负责对函数的输入参数的合法性检查, ...

  8. Prisma GraphQL 服务器 生产者 "https://www.prisma.io"

    Prisma   一个 GraphQL  服务器 生产者     "https://www.prisma.io" , 关注一下

  9. Redis和memcahce的区别【转】

    先给大家讲一个基本知识点:数据库分类大致分为两类,关系型数据库和非关系型数据库.如果详细区分的话,还可以继续分下去. Redis不仅仅是缓存数据库 面试的时候,很多人会问,Redis和memcahce ...

  10. TCP-IP详解学习笔记1

    TCP-IP详解学习笔记1 网关可以在互不相关的网络之间提供翻译功能: 体系结构: 协议和物理实现,实际上是一组设计决策. TCP/IP协议族允许计算机,智能手机,嵌入式设备之间通信: TCP/IP是 ...