<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Petrozavodsk Winter-2018. Jagiellonian U Contest

      A. XOR

      求出所有數的異或和$sum$,將所有數and上$sum$,然后求線性基,則選取$sum$的所有$1$對應的基最優。

      時間復雜度$O(n\log x)$。

      #include<cstdio>
      #include<cstdlib>
      #include<algorithm>
      #include<ctime>
      using namespace std;
      typedef long long ll;
      int Case,n,i,j;ll ans,sum,A,B,a[100],x,v[111111],pool[100];
      const int N=20;
      ll cal(){
      	ll ans=sum;
      	for(int S=0;S<1<<n;S++){
      		ll A=sum,B=0;
      		for(i=0;i<n;i++)if(S>>i&1)A^=v[i],B^=v[i];
      		A-=B;
      		if(A<0)A=-A;
      		if(A<ans)ans=A;
      	}
      	return ans;
      }
      void print(ll x){
      	for(int i=11;~i;i--)printf("%lld",x>>i&1);
      	puts("");
      }
      ll myabs(ll x){return x>0?x:-x;}
      ll solve1(int x){
      	ll cur=a[x];
      	for(int i=x-1;~i;i--)if(sum>>i&1){
      		cur^=a[i];
      	}
      	return myabs(cur-(sum^cur));
      }
      ll solve2(int x){
      	ll cur=0;
      	for(int i=x-1;~i;i--){
      		cur=max(cur,cur^a[i]);
      	}
      	return myabs(cur-(sum^cur));
      }
      int main(){
      	//srand(time(NULL));
      	scanf("%d",&Case);
      	while(Case--){
      		scanf("%d",&n);
      		//n=rand()%10+1;
      		sum=0;
      		for(i=0;i<61;i++)a[i]=0;
      		for(i=0;i<n;i++){
      			scanf("%lld",&x);
      			//x=rand()%1000;
      			v[i]=x;
      			sum^=x;
      			for(j=60;~j;j--)if(x>>j&1){
      				if(a[j])x^=a[j];
      				else {a[j]=x;break;}
      			}
      		}
      		
      		//ll vio=cal();
      		
      		for(i=0;i<61;i++)for(j=i+1;j<61;j++)if(a[j]>>i&1)a[j]^=a[i];
      		
      		for(i=60;~i;i--)if(sum>>i&1)break;
      		int lim=i;
      		if(lim>=0){
      			for(i=0;i<61;i++)pool[i]=a[i]&sum,a[i]=0;
      			for(i=0;i<61;i++){
      				x=pool[i];
      				for(j=60;~j;j--)if(x>>j&1){
      					if(a[j])x^=a[j];
      					else {a[j]=x;break;}
      				}
      			}
      			for(i=0;i<61;i++)for(j=i+1;j<61;j++)if(a[j]>>i&1)a[j]^=a[i];
      			ans=min(sum,min(solve1(lim),solve2(lim)));
      		}else{
      			ans=0;
      		}
      		
      		/*A=sum,B=0;*/
      		
      		//print(sum);
      		//for(i=60;~i;i--)if(a[i])print(a[i]);
      		
      		/*ans=sum;
      		for(i=60;~i;i--)if((A^a[i])>=(B^a[i])&&(A^a[i])-(B^a[i])<ans){
      			A^=a[i];
      			B^=a[i];
      			ans=A-B;
      		}*/
      		/*if(ans==vio)puts("OK");else{
      			printf("vio=%lld ans=%lld\n",vio,ans);
      			printf("%d\n",n);
      			for(i=0;i<n;i++)printf("%lld ",v[i]);
      			puts("");
      			while(1);
      		}*/
      		printf("%lld\n",ans);
      	}
      }
      

        

      B. Tribute

      按題意模擬即可。

      #include<bits/stdc++.h>
      using namespace std;
      int casenum, casei;
      typedef unsigned int UI;
      int n;
      vector<UI>vt, wt;
      multiset<UI>sot;
      multiset<UI>ans;
      bool solve()
      {
      	for(int i = 1; i <= n; ++i)
      	{
      		int x = *sot.begin();
      		ans.insert(x);
      //		printf("x = %d\n", x);
      //		for(auto y : vt)printf("%d ", y); puts("");
      		wt.clear();
      		for(auto y : vt)
      		{
      			int z = x + y;
      //			printf("%d\n", z);
      			if(sot.find(z) == sot.end())return 0;
      			sot.erase(sot.find(z));
      			wt.push_back(z);
      		}
      		for(auto y : wt)vt.push_back(y);
      	}
      	return 1;
      }
      int main()
      {
      	scanf("%d", &casenum);
      	for(casei = 1; casei <= casenum; casei ++)
      	{
      		scanf("%d", &n);
      		int m = (1 << n) - 1;
      		vt.clear(); vt.push_back(0);
      		sot.clear();
      		ans.clear();
      		for(int i = 1; i <= m; ++i)
      		{
      			int x; scanf("%d", &x);
      			sot.insert(x);
      		}
      		if(!solve())puts("NO");
      		else
      		{
      			int id = 0;
      			for(auto it : ans)printf("%d%c", it, ++id == n ? '\n' : ' ');
      		}
      	}
      }
      

        

      C. Boardroom Meeting

      CDQ分治+掃描線樹狀數組,時間復雜度$O(n\log^2n)$。

      #include<cstdio>
      #include<algorithm>
      using namespace std;
      const int N=200010;
      int Case,n,i,a[N],b[N],c[N],ans,f[N],qa[N],qb[N],bit[N],vis[N],T;
      inline void up(int&a,int b){a<b?(a=b):0;}
      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);}
      inline void ask(int x,int&p){for(;x;x-=x&-x)if(vis[x]==T)up(p,bit[x]);}
      inline bool cmp(int x,int y){return a[x]<a[y];}
      void solve(int l,int r){
      	if(l==r){
      		up(ans,++f[l]);
      		return;
      	}
      	int mid=(l+r)>>1,i,j,ca=0,cb=0;
      	solve(l,mid);
      	for(i=l;i<=mid;i++)qa[++ca]=i;
      	for(;i<=r;i++)qb[++cb]=i;
      	sort(qa+1,qa+ca+1,cmp);
      	sort(qb+1,qb+cb+1,cmp);
      	T++;
      	for(i=j=1;i<=cb;i++){
      		while(j<=ca&&a[qa[j]]<a[qb[i]]){
      			ins(b[qa[j]],f[qa[j]]);
      			j++;
      		}
      		ask(b[qb[i]]-1,f[qb[i]]);
      	}
      	solve(mid+1,r);
      }
      int main(){
      	scanf("%d",&Case);
      	while(Case--){
      		scanf("%d",&n);
      		for(i=1;i<=n;i++)scanf("%d",&a[i]);
      		for(i=1;i<=n;i++)scanf("%d",&b[i]),c[i]=b[i];
      		sort(c+1,c+n+1);
      		for(i=1;i<=n;i++)b[i]=lower_bound(c+1,c+n+1,b[i])-c;
      		for(i=1;i<=n;i++)f[i]=0;
      		ans=0;
      		solve(1,n);
      		printf("%d\n",ans);
      	}
      }
      /*
      1
      6
      1 2 6 3 4 6
      4 1 3 5 7 7
      */
      

        

      D. Secret Santa

      第二類斯特林數容斥,時間復雜度$O(a\log n)$。

      #include<cstdio>
      const int N=2010,P=1000000007;
      int n,a,i,j,Case,fac[N],S[N][N];
      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;}
      int T(int m,int n){
        int ans=0;
        for(int k=0;k<m;k++){
          int t=fac[k];
          if((k+m)%2)t=(P-t)%P;
          t=1LL*t*po(k+1,n)%P;
          t=1LL*t*S[m][k+2]%P;
          ans=(ans+t)%P;
        }
        return ans;
      }
      int main(){
        for(i=0;i<N;i++)for(j=0;j<N;j++){
          if(i>=1&&j==0){S[i][j]=0;continue;}
          if(i==j){S[i][j]=1;continue;}
          if(j>=1&&j<i)S[i][j]=(1LL*S[i-1][j]*j+S[i-1][j-1])%P;
        }
        for(fac[0]=i=1;i<N;i++)fac[i]=1LL*fac[i-1]*i%P;
        scanf("%d",&Case);
        while(Case--){
          scanf("%d%d",&n,&a);a++;n-=a-2;
          printf("%d\n",T(a,n));
        }
      }
      

        

      E. Guessing Game

      狀壓DP,設$f[S]$表示$S$情況下最優策略最壞需要的步數,其中$S$是個$k$位$3$進制數,分別表示每一位未詢問、已詢問且回答為$0$、已詢問且回答為$1$的情況。

      用高維前綴和預處理出所有$f[S]=0$的狀態,剩下的狀態枚舉詢問哪一位轉移即可。

      時間復雜度$O(3^kk)$。

      #include<cstdio>
      #include<algorithm>
      using namespace std;
      const int N=13,M=1600000;
      int p[20],Case,n,m,i,j,k,f[M],c[M];char s[20];
      inline int get(int x,int y){return x/p[y]%3;}
      int main(){
      	for(p[0]=i=1;i<20;i++)p[i]=p[i-1]*3;
      	scanf("%d",&Case);
      	while(Case--){
      		scanf("%d%d",&n,&k);
      		m=p[k];
      		for(i=0;i<m;i++)c[i]=0;
      		for(i=1;i<=n;i++){
      			scanf("%s",s);
      			int t=0;
      			for(j=0;j<k;j++)t=t*3+s[j]-'0';
      			c[t]++;
      		}
      		for(i=0;i<k;i++)for(j=0;j<m;j++)if(get(j,i)==2){
      			c[j]+=c[j-p[i]]+c[j-p[i]*2];
      		}
      		for(i=0;i<m;i++){
      			if(c[i]<=1){f[i]=0;continue;}
      			f[i]=M;
      			for(j=0;j<k;j++)if(get(i,j)==2){
      				f[i]=min(f[i],max(f[i-p[j]],f[i-p[j]*2]));
      			}
      			f[i]++;
      		}
      		printf("%d\n",f[m-1]);
      	}
      }
      

        

      F. Flat Earth

      按題意模擬即可。

      #include<stdio.h>
      #include<math.h>
      
      int casenum, casei, a[10];
      const double PI = acos(-1.0);
      
      int main()
      {
      	scanf("%d", &casenum);
      	for(casei = 1; casei <= casenum; casei ++){
      		for(int i = 1; i <= 8; i ++){
      			scanf("%d", &a[i]);
      		}
      		printf("%.10f\n", PI * a[4] * a[4]);
      	}
      }
      

        

      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))$。

      #include<cstdio>
      #include<algorithm>
      using namespace std;
      const int N=1100000;
      int Case,n,m,all,i,j,a[N];char s[100];
      int h,t,d[N],p[N],x,y,z,q[N];
      int f[N],ans,ce;
      struct E{
      	int x,y,z;
      	E(){}
      	E(int _x,int _y,int _z){x=_x,y=_y,z=_z;}
      }e[N*20];
      inline bool cmp(const E&a,const E&b){return a.z<b.z;}
      inline void ext(int x,int y,int z){
      	if(y<d[x]){
      		d[x]=y;
      		p[x]=z;
      		q[++t]=x;
      	}
      }
      int F(int x){return f[x]==x?x:f[x]=F(f[x]);}
      inline void add(int x,int y,int z){
      	if(x!=y)e[++ce]=E(x,y,z);
      }
      int main(){
      	scanf("%d",&Case);
      	while(Case--){
      		scanf("%d%d",&n,&m);
      		all=1<<n;
      		for(i=0;i<all;i++)d[i]=N;
      		for(i=1;i<=m;i++){
      			scanf("%s",s);
      			a[i]=0;
      			for(j=0;j<n;j++)a[i]=a[i]*2+(s[j]=='L');
      			d[a[i]]=0,p[a[i]]=i;
      		}
      		h=1,t=0;
      		for(i=0;i<all;i++)if(!d[i])q[++t]=i;
      		while(h<=t){
      			x=q[h++];
      			y=d[x]+1;
      			z=p[x];
      			for(i=0;i<n;i++)ext(x^(1<<i),y,z);
      		}
      		ce=0;
      		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);
      		for(i=1;i<=m;i++)f[i]=i;
      		ans=0;
      		sort(e+1,e+ce+1,cmp);
      		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;
      		printf("%d\n",ans);
      	}
      }
      

        

      H. Masterpiece

      若不考慮每個點是被第幾次走過的,則方案唯一,$O(n)$模擬求出方案后統計分岔點個數$t$,則答案為$2^t$。

      #include<stdio.h>
      #include<iostream>
      #include<string.h>
      #include<string>
      #include<ctype.h>
      #include<math.h>
      #include<set>
      #include<map>
      #include<vector>
      #include<queue>
      #include<bitset>
      #include<algorithm>
      #include<time.h>
      using namespace std;
      void fre() {  }
      #define MS(x, y) memset(x, y, sizeof(x))
      #define rt 1,1,n
      #define ls o<<1
      #define rs o<<1|1
      #define mid (l+r>>1)
      #define lson ls,l,mid
      #define rson rs,mid+1,r
      typedef long long LL;
      typedef unsigned long long UL;
      typedef unsigned int UI;
      template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
      template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
      const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
      template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
      int casenum, casei;
      int n;
      int r[N], c[N];
      //try go to (y, x)
      bool flag = 1;
      int r1, r2;
      int c1, c2;
      bool doit(int y, int x)
      {
          if(r1 == r2 && c1 == c2)return flag = 1;
          if(y > n || x > n)return 0;
          if(!r[y] || ! c[x])return 0;
          --r[y];
          --c[x];
          return flag = 1;
      }
      int solve()
      {
          int ans = 1;
          r1 = 1, c1 = 1;
          r2 = 1, c2 = 1;
          doit(1, 1); --r[1]; --c[1];
          while(1)
          {
              flag = 0;
              if(r1 == r2 && c1 == c2)
              {
                  if(r1 == n && c1 == n)
                  {
                      return ans;
                  }
                  int rnum = r[r1];
                  int cnum = c[c1];
                  if(rnum && cnum)
                  {
                      ans = ans * 2 % Z;
                      for(int i = 1; i <= rnum; ++i)
                      {
                          if(!doit(r1, ++c1))return 0;
                      }
                      for(int i = 1; i <= cnum; ++i)
                      {
                          if(!doit(++r2, c2))return 0;
                      }
                  }
                  else if(rnum)
                  {
                      if(!doit(r1, ++c1))return 0;
                      ++c2;
                  }
                  else if(cnum)
                  {
                      if(!doit(++r1, c1))return 0;
                      ++r2;
                  }
                  else return 0;
              }
              while(r1 < r2)
              {
                  if(r[r1])
                  {
                      if(!doit(r1, ++c1))return 0;
                  }
                  else
                      if(!doit(++r1, c1))return 0;
              }
              while(r2 < r1)
              {
                  if(r[r2])
                  {
                      if(!doit(r2, ++c2))return 0;
                  }
                  else
                      if(!doit(++r2, c2))return 0;
              }
              while(c1 < c2)
              {
                  if(c[c1])
                  {
                      if(!doit(++r1, c1))return 0;
                  }
                  else
                      if(!doit(r1, ++c1))return 0;
              }
              while(c2 < c1)
              {
                  if(c[c2])
                  {
                      if(!doit(++r2, c2))return 0;
                  }
                  else
                      if(!doit(r2, ++c2))return 0;
              }
              if(!flag)return 0;
          }
      }
      int main()
      {
      	scanf("%d", &casenum);
      	for(casei = 1; casei <= casenum; ++casei)
      	{
              scanf("%d", &n);
              //int n = rand() % 10 + 1;
              for(int i = 1; i <= n; ++i)
              {
                  scanf("%d", &r[i]);
                  //r[i] = rand() % (n + 1);
              }
              for(int i = 1; i <= n; ++i)
              {
                  scanf("%d", &c[i]);
                  //c[i] = rand() % (n + 1);
              }
              int ans = solve();
              for(int i = 1; i <= n; ++i)
              {
                  if(r[i] || c[i])ans = 0;
              }
              printf("%d\n", ans);
      	}
      	return 0;
      }
      
      /*
      【trick&&吐槽】
      
      
      【題意】
      
      
      【分析】
      
      
      【時間復雜度&&優化】
      
      100
      5
      3 3 3 3 3
      1 4 4 3 3
      
      4
      4 2 2 4
      4 2 2 4
      
      */
      

        

      I. Don’t Split The Atom!

      勝負只取決于$n$的奇偶性。

      #include<stdio.h>
      #include<math.h>
      
      int casenum, casei, a[10];
      const double PI = acos(-1.0);
      
      int main()
      {
      	scanf("%d", &casenum);
      	for(casei = 1; casei <= casenum; casei ++){
      		int n;
      		scanf("%d", &n);
      		puts(n & 1 ? "B" : "A");
      	}
      }
      

        

      J. Bobby Tables

      組合數可以看作長度為$k$的一個區間除以長度為$k$的一個前綴。

      枚舉每個$k$作為前綴,二分對應的區間,取對數加速判定,在附近配合取模判定即可。

      時間復雜度$O(m\log m)$。

      #include<cstdio>
      #include<cmath>
      #include<algorithm>
      using namespace std;
      typedef long double ld;
      const int N=200010,P=1000000007,K=20;
      const ld eps=1e-2;
      int Case,n,m,i,a[N],fac[N],inv[N],mul;
      ld Log[N],s[N],sum;
      inline bool check(int n,int m){
      	ld A=s[n]-s[n-m]-s[m];
      	if(fabs(A-sum)>eps)return 0;
      	int B=1LL*fac[n]*inv[n-m]%P*inv[m]%P;
      	if(B!=mul)return 0;
      	puts("YES");
      	printf("%d %d\n",n,m);
      	return 1;
      }
      inline void solve(){
      	scanf("%d%d",&n,&m);
      	sum=0;
      	mul=1;
      	for(i=1;i<=n;i++){
      		scanf("%d",&a[i]);
      		mul=1LL*mul*a[i]%P;
      		sum+=Log[a[i]];
      	}
      	for(i=1;i<=m;i++){
      		//[x,x+i-1]/[1..i]
      		//C(x+i-1,i)
      		//x+i-1>=i
      		//1<=x<=m+1-i
      		//x+i-1<=m
      		int l=1,r=m+1-i;
      		while(l<=r){
      			int mid=(l+r)>>1;
      			ld A=s[mid+i-1]-s[mid-1]-s[i];
      			if(fabs(A-sum)<eps){
      				for(int j=max(mid-K,1);j<=min(m+1-i,mid+K);j++)if(check(j+i-1,i))return;
      				break;
      			}
      			if(A<sum)l=mid+1;else r=mid-1;
      		}
      	}
      	puts("NO");
      }
      int main(){
      	for(i=1;i<N;i++)Log[i]=log2(i);
      	for(i=1;i<N;i++)s[i]=s[i-1]+Log[i];
      	for(inv[0]=inv[1]=1,i=2;i<N;i++)inv[i]=1LL*(P-inv[P%i])*(P/i)%P;
      	for(fac[0]=i=1;i<N;i++)fac[i]=1LL*fac[i-1]*i%P;
      	for(i=1;i<N;i++)inv[i]=1LL*inv[i-1]*inv[i]%P;
      	scanf("%d",&Case);
      	while(Case--){
      		solve();
      	}
      }
      

        

      K. Triples

      長鏈剖分或樹分治經典題。

      #include<cstdio>
      #include<vector>
      #include<algorithm>
      #include<cstring>
      #define pb push_back
      #define V vector
      #define N 200010
      using namespace std;
      typedef long long ll;
      typedef pair<int,ll>P;
      int Case;
      int n,i,x,y,g[N],v[N<<1],nxt[N<<1],ed,f[N],del[N];ll ans;V<P>h[N];
      inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
      inline bool cmp(V<int>*a,V<int>*b){return a->size()>b->size();}
      template<class C>inline C&get(V<C>&a,size_t x){return a[a.size()-x-1];}
      V<int>*dfs(int x,int y){
        V<V<int>*>t;
        for(int i=g[x];i;i=nxt[i])if(v[i]!=y)t.pb(dfs(v[i],x));
        if(!t.size())return new V<int>(1,1);
        sort(t.begin(),t.end(),cmp);
        V<int>*a=t[0];
        a->pb(1);
        if(t.size()==1)return a;
        V<ll>b;
        b.resize(t[1]->size()+1,0);
        for(int i=1;i<t.size();i++){
          V<int>*u=t[i];
          for(int j=1;j<=u->size();j++){
            int ch=get(*u,j-1),&rt=get(*a,j);ll&rd=get(b,j);
            ans+=1LL*ch*rd;
            rd+=1LL*ch*rt;
            rt+=ch;
          }
        }
        for(int i=1;i<b.size();i++){
          h[x].pb(P(i,get(b,i)));
          ans-=1LL*get(b,i)*get(*a,i);
        }
        return a;
      }
      void cal(int x,int y){
        f[x]=1;
        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]];
      }
      inline int findroot(int x){
        cal(x,-1);
        int n=f[x],t=0,y=-1;
        do{
          t=0;
          for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&!del[v[i]]&&2*f[v[i]]>n){
            y=x,x=v[i],t=1;
            break;
          }
        }while(t);
        return x;
      }
      inline void work(V<V<int> >&d,V<V<P> >&q,int k,bool rt,int x){
        int st=k==1?0:d.size()-1,en=k==1?d.size():-1;V<int>a(1,rt); 
        for(int i=st;i!=en;i+=k){
          V<int>D=d[i];
          for(V<P>::iterator p=q[i].begin();p!=q[i].end();p++){
            int j=p->first;
            if(j<a.size())ans+=1LL*a[j]*p->second;
          }
          a.resize(max(a.size(),D.size()),0);
          for(int j=0;j<D.size();j++)a[j]+=D[j];
        }
        if(rt)for(V<P>::iterator p=h[x].begin();p<h[x].end();p++){
          int j=p->first;
          if(j<a.size())ans+=1LL*a[j]*p->second;
        }
      }
      void dfsd(int x,int y,int z,V<int>&d){
        if(z==d.size())d.pb(1);else d[z]++;
        for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&!del[v[i]])dfsd(v[i],x,z+1,d);
      }
      void dfsq(int x,int y,int z,V<P>&q){
        for(V<P>::iterator i=h[x].begin();i<h[x].end();i++){
          int t=i->first-z;
          if(t>=0)q.pb(P(t,i->second));
        }
        for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&!del[v[i]])dfsq(v[i],x,z+1,q);
      }
      void solve(int x){
        int y=findroot(x);
        del[y]=1;
        for(int i=g[y];i;i=nxt[i])if(!del[v[i]])solve(v[i]);
        V<V<int> >d;V<V<P> >q;
        for(int i=g[y];i;i=nxt[i])if(!del[v[i]]){
          V<int>A(1,0);
          dfsd(v[i],-1,1,A);
          d.pb(A);
          V<P>B;
          dfsq(v[i],-1,1,B);
          q.pb(B);
        }
        work(d,q,1,1,y),work(d,q,-1,0,y);
        del[y]=0;
      }
      int main(){
        scanf("%d",&Case);
        while(Case--){
          i=x=y=0;
          memset(g,0,sizeof g);
          memset(f,0,sizeof f);
          memset(v,0,sizeof v);
          memset(nxt,0,sizeof nxt);
          ed=0;
          memset(del,0,sizeof del);
          ans=0;
          for(i=0;i<N;i++)h[i].clear();
          scanf("%d",&n);
          for(i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            x--,y--;
            add(x,y),add(y,x);
          }
          dfs(0,-1);
          solve(0);
          printf("%lld\n",ans);
        }
      }
      

        

      L. Related Languages

      枚舉$O(nm)$對區間右端點,左端點的取值滿足單調性,雙指針即可。

      時間復雜度$O(nm)$。

      #include<cstdio>
      const int N=4010;
      int Case,n,m,i,j,k,ans,g[N*3];
      char a[N],b[N],f[N][N];
      int w[N*3],V;
      int main(){
        scanf("%d",&Case);
        while(Case--){
          scanf("%d%d%d%s%s",&n,&m,&V,a+1,b+1);
          ans=0;
          for(i=1;i<=n;i++)for(j=1;j<=m;j++)f[i][j]=a[i]!=b[j];
          for(i=0;i<=N+N+5;i++)g[i]=w[i]=0;
          for(i=1;i<=n;i++)for(j=1;j<=m;j++){
            k=i-j+N;
            g[k]++;
            w[k]+=f[i][j];
            int G=g[k],W=w[k];
            while(G>0&&W>V){
              G--;
              W-=f[i-G][j-G];
            }
            g[k]=G;
            w[k]=W;
            if(G>ans)ans=G;
          }
          printf("%d\n",ans);
        }
      }
      

        

      posted @ 2018-03-06 22:00  Claris  閱讀(1157)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 青青草无码免费一二三区| 国产精品久久久久精品日日 | 99久久精品久久久久久清纯| 精品偷拍一区二区三区| 亚洲欧美一区二区成人片| 亚洲国产精品综合久久网络| 精品无码三级在线观看视频| 国产精品三级一区二区三区 | 精品无码久久久久久尤物| 无码人妻av免费一区二区三区| 亚洲午夜理论无码电影| 中文在线а√天堂| 视频一区视频二区视频三 | 免费观看羞羞视频网站| 日韩午夜一区二区福利视频| 久久精品无码av| 久久精品国产清自在天天线| 亚洲av成人在线一区| 午夜国产精品福利一二| 中文字幕av日韩有码| 国产精品亚洲二区在线播放| av天堂午夜精品一区| 精品日本免费一区二区三区| 国产一区二区午夜福利久久| 老鸭窝| 亚洲av永久无码精品天堂久久| 波多野结衣高清一区二区三区| √新版天堂资源在线资源 | 91精品91久久久久久| av天堂午夜精品一区| 亚洲精品国产精品国在线| 日韩精品亚洲专在线电影| 在线看免费无码av天堂| 竹菊影视欧美日韩一区二区三区四区五区| 2021最新国产精品网站| 久久精品夜色噜噜亚洲av| 人妻中文字幕亚洲精品| 国产一区二区在线影院| 亚洲另类欧美在线电影| 国产精品自在自线视频| 99国产精品国产精品久久|