zoukankan      html  css  js  c++  java
  • csps-模拟7778lrd两试

    题面:https://www.cnblogs.com/Juve/articles/11707775.html

    位运算:

    大力分类讨论

    第一次发现若a^b=c,则c^b=a,c^a=b

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define int long long
    #define re register
    using namespace std;
    inline int read(){
    	re int x=0,f=1;re char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    int t,a,o,x;
    inline int q_pow(re int a,re int b){
    	re int res=1;
    	while(b){
    		if(b&1) res=res*a;
    		a=a*a;
    		b>>=1;
    	}
    	return res;
    }
    inline int calc(re int x){
    	re int res=0;
    	while(x){
    		if(x&1) ++res;
    		x>>=1;
    	}
    	return res;
    }
    signed main(){
    	t=read();
    	while(t--){
    		a=read(),o=read(),x=read();
    		if(a!=-1&&o==-1&&x==-1){//only have and
    			puts("inf");
    			continue;
    		}
    		if(a==-1&&o!=-1&&x==-1){//only have or
    			printf("%lld
    ",q_pow(3,calc(o)));
    			continue;
    		}
    		if(a==-1&&o==-1&&x!=-1){//only have xor
    			puts("inf");
    			continue;
    		}
    		if(a==-1&&o!=-1&&x!=-1){//no and
    			re int t=o^x;
    			if((t|o)!=o) puts("0");
    			else printf("%lld
    ",q_pow(2,calc(x)));
    			continue;
    		}
    		if(a!=-1&&o==-1&&x!=-1){//no or
    			re int t=x^a;
    			if((a|t)!=t) puts("0");
    			else printf("%lld
    ",q_pow(2,calc(x)));
    			continue;
    		}
    		if(a!=-1&&o!=-1&&x==-1){//no xor
    			if((a|o)!=o) puts("0");
    			else printf("%lld
    ",q_pow(2,calc(a^o)));
    			continue;
    		}
    		if(a!=-1&&o!=-1&&x!=-1){//have all
    			if((a|o)!=o||(a^o)!=x) puts("0");
    			else printf("%lld
    ",q_pow(2,calc(x)));
    			continue;
    		}
    	}
    	return 0;
    }
     

    集合论:

    好像我打的不是正解

    大力set模拟集合,在集合外加一个bas懒标记,表示集合中的数被增加了多少,查询x是否在集合中出现在set中查x-bas,插入插x-bas,

    保证在加完bas后得到x

    本题卡常,unordered_map也会T,只要把清空set改成新建一个空set然后赋值

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<unordered_set>
     6 #define re register
     7 using namespace std;
     8 const int MAXN=3e6+5;
     9 char xch,xB[1<<15],*xS=xB,*xTT=xB;
    10 #define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
    11 inline int read(){
    12     re int x=0,f=1;re char ch=getc();
    13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    14     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getc();}
    15     return x*f;
    16 }
    17 int m,bas=0,sta[MAXN],top=0;
    18 unordered_set<int>s;
    19 long long ans=0ll;
    20 signed main(){
    21     m=read();
    22     for(re int i=1,opt,sum;i<=m;++i){
    23         opt=read();
    24         if(opt==3){
    25             if(s.size()) ++bas;
    26         }
    27         if(opt==4){
    28             if(s.size()) --bas;
    29         }
    30         if(opt==1){
    31             sum=read();
    32             for(re int j=1,x;j<=sum;++j){
    33                 x=read();
    34                 if(s.find(x-bas)==s.end()){
    35                     s.insert(x-bas);
    36                     ans+=(x-bas);
    37                 }
    38             }
    39         }
    40         if(opt==2){
    41             sum=read();
    42             top=ans=0;
    43             for(re int j=1,x;j<=sum;++j){
    44                 x=read();
    45                 if(s.find(x-bas)!=s.end()){
    46                     sta[++top]=x-bas;
    47                     ans+=(x-bas);
    48                 }
    49             }
    50             unordered_set<int>t;
    51             swap(t,s);
    52             while(top) s.insert(sta[top--]);
    53         }
    54         printf("%lld
    ",ans+(long long)bas*s.size());
    55     }
    56     return 0;
    57 }
    View Code

    连连看:我咕了

    串串香:

    正解是kmp,被hash完美过掉

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 #define ull unsigned long long
     7 using namespace std;
     8 const int MAXN=1e6+5;
     9 const int mod=13331;
    10 int t,n,m,ans;
    11 ull pre[MAXN<<1],h[MAXN<<1];
    12 char ch[MAXN];
    13 signed main(){
    14     pre[0]=1;
    15     for(int i=1;i<=2*MAXN-3;++i){
    16         pre[i]=pre[i-1]*mod;
    17     }
    18     scanf("%lld",&t);
    19     while(t--){
    20         scanf("%lld%lld",&n,&m);
    21         scanf("%s",ch+1);
    22         for(int i=1;i<=m;++i){
    23             h[i]=h[i-1]*mod+ch[i]-'A'+1;
    24         }
    25         ans=0;
    26         if(n==1){
    27             for(int i=m-1;i>=1;--i){
    28                 if(h[i]==h[m]-h[m-i]*pre[i]){
    29                     ans=i;
    30                     break;
    31                 }
    32             }
    33             if(ans==0) ans=-1;
    34             printf("%lld
    ",ans);
    35             continue;
    36         }
    37         for(int i=1;i<=m;++i){
    38             h[i+m]=h[i+m-1]*mod+ch[i]-'A'+1;
    39         }
    40         for(int i=2*m-1;i>=1;--i){
    41             if(h[i]==h[2*m]-h[2*m-i]*pre[i]){
    42                 ans=2*m-i;
    43                 break;
    44             }
    45         }
    46         printf("%lld
    ",n*m-ans);
    47     }
    48     return 0;
    49 }
    View Code

    糊涂图:除了qj啥都不会

    木叶下:

    如果u,v相等,那么答案就是树的直径

    如果u,v不想等,那么u,v,lca会构成一个环,环上的点会被保护起来,那么答案就是u,v路径上的点向下延伸的最长长度和lca处不走lca子树的最长长度

    先求出对于每个点x,x的子树中的前三长的链的长度和对应的儿子

    然后dfs求出每一个x,不走x的子树能走的最长长度,再求出每一个x,他的父亲不走x的最大长度,这个可以倍增,且可以用前三长链求出

    然后倍增solve答案,注意在lca处是由两条路径走到的,所以要求前三大的链,保证有一条链既不过u,也不过v

     

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int MAXN=200005;
    int n,m,du[MAXN],ans=1;
    int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0;
    void add(int u,int v){
    	++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
    }
    queue<int>q;
    int fa[MAXN][23],deep[MAXN];
    bool flag=0;
    int tot=0;
    void DFS(int x,int f){
    	for(int i=pre[x];i;i=nxt[i]){
    		int y=to[i];
    		if(y==f) continue;
    		DFS(y,x);
    	}
    }
    pair<int,int>mxx[MAXN][3];
    void dfs(int x,int f){
    	deep[x]=deep[f]+1;
    	fa[x][0]=f;
    	for(int i=pre[x];i;i=nxt[i]){
    		int y=to[i];
    		if(y==f) continue;
    		dfs(y,x);
    		int k=mxx[y][0].first+1;
    		if(k>mxx[x][2].first){
    			mxx[x][2].first=k;
    			mxx[x][2].second=y;
    		}
    		if(mxx[x][2].first>mxx[x][1].first){
    			swap(mxx[x][2],mxx[x][1]);
    		}
    		if(mxx[x][1].first>mxx[x][0].first){
    			swap(mxx[x][0],mxx[x][1]);
    		}
    	}
    }
    int get(int x){
    	int f=fa[x][0];
    	for(int i=0;i<=2;++i){
    		if(mxx[f][i].second!=x)
    			return mxx[f][i].first;
    	}
    	return 0;
    }
    int gett(int x,int y){
    	int f=fa[x][0];
    	for(int i=0;i<=3;++i){
    		if(mxx[f][i].second!=x&&mxx[f][i].second!=y)
    			return mxx[f][i].first;
    	}
    	return 0;
    }
    int w[MAXN],ww[MAXN][23];
    void dfs(int x){
    	ww[x][0]=get(x);
    	w[x]=max(w[fa[x][0]],ww[x][0])+1;
    	for(int i=pre[x];i;i=nxt[i]){
    		int y=to[i];
    		if(y==fa[x][0]) continue;
    		dfs(y);
    	}
    }
    int solve(int x,int y){
    	if(deep[x]>deep[y]) swap(x,y);
    	int k=deep[y]-deep[x],res=mxx[y][0].first;
    	for(int i=0;i<=20;++i)
    		if((1<<i)&k){
    			res=max(res,ww[y][i]);
    			y=fa[y][i];
    		}
    	if(x==y){
    		res=max(res,w[x]);
    		return res;
    	}
    	res=max(res,mxx[x][0].first);
    	for(int i=20;i>=0;--i)
    		if(fa[x][i]!=fa[y][i]){
    			res=max(res,max(ww[x][i],ww[y][i]));
    			x=fa[x][i],y=fa[y][i];
    		}
    	res=max(res,max(gett(x,y),w[fa[x][0]]));
    	return res;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1,u,v;i<n;++i){
    		scanf("%d%d",&u,&v);
    		add(u,v),add(v,u);
    		++du[u],++du[v];
    		if(abs(u-v)!=1) flag=1;
    	}
    	if(!flag){
    		scanf("%d",&m);
    		while(m--){
    			int u,v;
    			scanf("%d%d",&u,&v);
    			if(u==v) printf("%d
    ",n/2);
    			else{
    				if(v<u) swap(u,v);
    				printf("%d
    ",max(n-v,u-1));
    			}
    		}
    		return 0;
    	}
    	for(int i=1;i<=n;++i){
    		if(du[i]<=1){
    			q.push(i);
    			deep[i]=1;
    			du[i]=-1;
    		}
    	}
    	while(!q.empty()){
    		int x=q.front();
    		q.pop();
    		for(int i=pre[x];i;i=nxt[i]){
    			int y=to[i];
    			if(du[y]==-1) continue;
    			--du[y];
    			if(du[y]<=1){
    				deep[y]=deep[x]+1;
    				ans=max(ans,deep[y]);
    				q.push(y);
    				du[y]=-1;
    			}
    		}
    	}
    	memset(deep,0,sizeof(deep));
    	dfs(1,0);dfs(1);
    	w[1]=0;
    	for(int i=1;i<=20;++i){
    		for(int j=1;j<=n;++j){
    			fa[j][i]=fa[fa[j][i-1]][i-1];
    			ww[j][i]=max(ww[j][i-1],ww[fa[j][i-1]][i-1]);
    		}
    	}
    	scanf("%d",&m);
    	while(m--){
    		int u,v;
    		scanf("%d%d",&u,&v);
    		if(u==v) printf("%d
    ",ans);
    		else printf("%d
    ",solve(u,v));
    	}
    	return 0;
    }
    

     

     

  • 相关阅读:
    关闭编辑easyui datagrid table
    sql 保留两位小数+四舍五入
    easyui DataGrid 工具类之 util js
    easyui DataGrid 工具类之 后台生成列
    easyui DataGrid 工具类之 WorkbookUtil class
    easyui DataGrid 工具类之 TableUtil class
    easyui DataGrid 工具类之 Utils class
    easyui DataGrid 工具类之 列属性class
    oracle 卸载
    “云时代架构”经典文章阅读感想七
  • 原文地址:https://www.cnblogs.com/Juve/p/11708468.html
Copyright © 2011-2022 走看看