• 17.11.10 全是模板的一上午


    • 大米饼的左偏树
      #include<iostream>
      #include<cstdio>
      #define N 1000005
      using namespace std;
      int n,m,fa[N],l[N],r[N],d[N],v[N];
      bool die[N];
      int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
      int merge(int x,int y)
      {
      	if(!x)return y;if(!y)return x;//树结构合并的递归边界 
      	if(v[x]>v[y])swap(x,y);//找到两个树根中键值最小的节点 
      	r[x]=merge(r[x],y);//右儿子插入操作(左偏树特性),将键值较大的树作为另一个树的右儿子 
      	if(d[r[x]]>d[l[x]])swap(l[x],r[x]);//维护左偏性质 
      	d[x]=d[r[x]]+1;//记录dis(左偏树的基础信息) 
      	return x;//返回根 
      }
      int main()
      {
      	scanf("%d",&n);
      	for(int i=1;i<=n;i++)scanf("%d",&v[i]);
      	for(int i=1;i<=n;i++)fa[i]=i;d[0]=-1;char ch[10];scanf("%d",&m);
      	
      	for(int i=1;i<=m;i++)
      	{
      		scanf("%s",ch);int x,y;
      		if(ch[0]=='M')//要求:合并团 
      		{
      			scanf("%d%d",&x,&y);
      	    	if(die[x]||die[y])continue;//若最小值已死,则命令无效 
      	    	int p=find(x),q=find(y);//并查集找出左偏树根 
      	    	if(p!=q)//不是同一棵左偏树 
      		    {
      				int t=merge(p,q);//左偏树合并,返回新根 
      				fa[p]=fa[q]=t;//维护并查集 
      	    	}
      	    }
      	    else//要求:询问团 
      	    {
      	    	scanf("%d",&x);
      	    	if(die[x])printf("0
      ");//人已死,命令无效输出0 
      	    	else 
      	    	{
      	    		int p=find(x);die[p]=1;//找到这个人所在团(左偏树),将其弄死 
      	    		printf("%d
      ",v[p]);//按照题目要求输出那个人的分数 
      	    		fa[p]=merge(l[p],r[p]);//分最低人死了,将其移出左偏树,左右儿子合并重建 
      	    		fa[fa[p]]=fa[p];//并查集变成初始化状态(相当于删除) 
      	    	}
      	    }
      	}
      	return 0;
      }  
    • P1177 【模板】快速排序
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<algorithm>
      using namespace std;
      int a[100005],n;
      int main()
      {
      	scanf("%d",&n);
      	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
      	sort(a+1,a+n+1);
      	for(int i=1;i<n;i++) printf("%d ",a[i]);
      	printf("%d",a[n]);
      	return 0;
      }
      
    • P1439 【模板】最长公共子序列
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<algorithm>
      using namespace std;
      int A[100005],B[100005],tmp[100005];
      int n;
      int LIS(int *a){
      	static int t[100005],p; p=0;
      	for(int i=1;i<=n;i++){
      		if(B[i]>t[p]||t==0) t[++p]=B[i];
      		else{
      			int l=lower_bound(t+1,t+p+1,B[i])-t;
      			t[l]=B[i];
      		}
      	}
      	return p;
      }
      int main()
      {
      	scanf("%d",&n);
      	for(int i=1; i<=n; i++)scanf("%d",&A[i]),tmp[A[i]]=i;
      	for(int i=1; i<=n; i++)scanf("%d",&B[i]),B[i]=tmp[B[i]];
      	int ans=LIS(B);
      	printf("%d",ans);
      	return 0;
      }
      
    • P3366 【模板】最小生成树 kruskal
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<algorithm>
      using namespace std;
      struct edge{
      	int u,v,w;
      	bool operator <(const edge &rtm) const{
      		return w<rtm.w;	
      	}
      }e[200005];
      int fa[5005];
      int n,m,ans;
      int find(int u){
      	return u==fa[u]?u:fa[u]=find(fa[u]);
      }
      int main()
      {
      	scanf("%d%d",&n,&m);
      	for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
      	sort(e+1,e+m+1);
      	for(int i=1;i<=n;i++) fa[i]=i;
      	for(int i=1,need=n-1;i<=m&&need;i++){
      		int u=e[i].u,v=e[i].v,w=e[i].w;
      		int fu=find(u),fv=find(v);
      		if(fu==fv) continue;
      		fa[fv]=fu; need--;
      		ans+=w;
      	}
      	printf("%d",ans);
      	return 0;
      }
      
    • P3366 【模板】最小生成树 prim
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<queue>
      using namespace std;
      struct node{
          int id,val;
          bool operator <(const node &rtm) const{
              return val>rtm.val;
          }
      };
      struct edge{
          int to,val,next;
      }e[200005*2];
      int head[5005];
      int n,m,ent=2;
      void add(int u,int v,int w){
          e[ent]=(edge){v,w,head[u]};
          head[u]=ent++;
      }
      void cmin(int &a,int b){
          if(a>b) a=b;
      }
      int prim(){
          static int d[5005],ans;
          memset(d,0x3f,sizeof(d));
          priority_queue<node>q; q.push((node){1,0});
          while(!q.empty()){
              int u=(q.top()).id,w=(q.top()).val; q.pop(); 
              if(!(~d[u])) continue;
              ans+=w; d[u]=-1;
              for(int i=head[u];i;i=e[i].next){
                  int v=e[i].to;
                  if(!(~d[v])) continue;
                  cmin(d[v],e[i].val);
                  q.push((node){v,d[v]});
              }
          }
          return ans;
      }
      int main()
      {
          scanf("%d%d",&n,&m);
          for(int i=1,u,v,w;i<=m;i++){
              scanf("%d%d%d",&u,&v,&w);
              add(u,v,w); add(v,u,w);
          }
          int ans=prim();
          printf("%d",ans);
          return 0;
      }
    • P3368 【模板】树状数组 2
      /*
      	(正反都可以)
      */
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      struct BIT{
      	int a[500005],n;
      	void init(int N){
      		n=N; memset(a,0,sizeof(a));
      	}
      	int lowbit(int x){
      		return x&-x;
      	}
      	void add(int l,int r,int w){
      		for(int i=l-1;i;i-=lowbit(i)) a[i]-=w;
      		for(int i=r;i;i-=lowbit(i)) a[i]+=w;
      	}
      	int query(int p){
      		int now=0;
      		for(int i=p;i<=n;i+=lowbit(i)) now+=a[i];
      		return now;
      	}
      }T;
      int a[500005];
      int n,m;
      int main()
      {
      	scanf("%d%d",&n,&m);	T.init(n);
      	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
      	int com,x,y,k;
      	for(int i=1;i<=m;i++){
      		scanf("%d",&com);
      		if(com==1){
      			scanf("%d%d%d",&x,&y,&k);
      			T.add(x,y,k);
      		}
      		else{
      			scanf("%d",&x);
      			printf("%d
      ",a[x]+T.query(x));
      		}
      	}
      	return 0;
      }
      
    • P3370 【模板】字符串哈希
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<algorithm>
      using namespace std;
      struct node{
          int a,b;
          bool operator ==(const node &rtm) const{
              return a==rtm.a&&b==rtm.b;
          }
          bool operator <(const node &rtm) const {
              return a==rtm.a?b<rtm.b:a<rtm.a;
          }
      }a[10005];
      int hash1(char *s){
          static int mod=19260817,bit=233;
          int now=0;
          for(int i=0;s[i];i++)
              now=(1ll*now*bit+s[i]-0)%mod;
          return now;
      }
      int hash2(char *s){
          static int mod=12356789,bit=79;
          int now=0;
          for(int i=0;s[i];i++)
              now=(1ll*now*bit+s[i]-0)%mod;
          return now;
      }
      int n;
      int main()
      {
          char s[1505];
          scanf("%d",&n);
          for(int i=1;i<=n;i++){
              scanf("%s",s);
              a[i]=(node){hash1(s),hash2(s)};
          }
          sort(a+1,a+n+1);
          n=unique(a+1,a+n+1)-a-1;
          printf("%d",n);
          return 0;
      }
      
    • P3371 【模板】单源最短路径
      #include<queue>
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #define node(a,b) (node){a,b}
      using namespace std;
      struct node{
          int id,val;
          bool operator <(const node &rtm) const{
              return val>rtm.val;
          }
      };
      struct edge{
          int to,val,next;
      }e[500005];
      int head[10005];
      int n,m,ent=2,S;
      void add(int u,int v,int w){
          e[ent]=(edge){v,w,head[u]};
          head[u]=ent++;
      }
      void Dijkstra(){
          static int dis[10005];
          static bool vis[10005];
          priority_queue<node> q;
          for(int i=1;i<=n;i++) dis[i]=2147483647;
          q.push(node(S,0)); dis[S]=0;
          while(!q.empty()){
              int u=(q.top()).id; q.pop();
              if(vis[u]) continue;
              vis[u]=1;
              for(int i=head[u];i;i=e[i].next){
                  int v=e[i].to;
                  if(dis[v]<=dis[u]+e[i].val) continue;
                  dis[v]=dis[u]+e[i].val;
                  q.push(node(v,dis[v]));
              }
          }
          for(int i=1;i<=n;i++) printf("%d ",dis[i]);
      }
      void SPFA(){
          static int dis[10005];
          static bool inq[10005];
          deque<int>q;
          for(int i=1;i<=n;i++) dis[i]=2147483647;
          q.push_back(S); dis[S]=0; inq[S]=1;
          while(!q.empty()){
              int u=q.front(); q.pop_front(); inq[u]=0;
              for(int i=head[u];i;i=e[i].next){
                  int v=e[i].to;
                  if(dis[v]<=dis[u]+e[i].val) continue;
                  dis[v]=dis[u]+e[i].val;
                  if(inq[v]) continue; inq[v]=1;
                  if(!q.empty()&&dis[q.front()]>dis[v]) q.push_front(v);
                  else q.push_back(v);
              }
          }
          for(int i=1;i<=n;i++) printf("%d ",dis[i]);
      }
      int main()
      {
          scanf("%d%d%d",&n,&m,&S);
          for(int i=1,u,v,w;i<=m;i++){
              scanf("%d%d%d",&u,&v,&w);
              add(u,v,w);
          }
          //Dijkstra();
          SPFA();
          return 0;
      }
    • P3375 【模板】KMP字符串匹配
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      char A[1000005],B[1000005];
      int nxt[1000005];
      void get_nxt(char *s){
      	nxt[0]=-1; int k=-1,j=0;
      	while(s[j]){
      		if(k==-1||s[j]==s[k]){
      			k++; j++; nxt[j]=k;
      		}
      		else k=nxt[k];
      	}
      }
      void matching(char *T,char *S){
      	int i=0,j=0;
      	while(T[i]){
      		if(j==-1||T[i]==S[j]) i++,j++;
      		else j=nxt[j];
      		if(~j&&!S[j]) printf("%d
      ",i-j+1);
      	}
      	for(int i=1;S[i-1];i++) printf("%d ",nxt[i]);
      }
      int main()
      {
      	scanf("%s",A); scanf("%s",B);
      	get_nxt(B);
      	matching(A,B);
      	return 0;
      }
      
    • P3383 【模板】线性筛素数
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      bool iscom[10000005];
      int prim[10000005],cnt;
      void Get(int N){
      	iscom[1]=1;
      	for(int i=2;i<=N;i++){
      		if(!iscom[i]) prim[++cnt]=i;
      		for(int j=1;j<=cnt&&i<=N/prim[j];j++){
      			iscom[i*prim[j]]=1;
      			if(i%prim[j]==0) break;
      		}
      	}
      }
      int main()
      {
      	int n,m;
      	scanf("%d%d",&n,&m);
      	Get(n);
      	while(m--){
      		scanf("%d",&n);
      		if(iscom[n]) puts("No");
      		else puts("Yes");
      	}
      	return 0;
      }
      
    • P3386 【模板】二分图匹配
      /*
      	匈牙利算法匹配时,那个vis标记是遇到一个v就标记,而不是进入一个dfs才标记。 
      */
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      struct edge{
      	int to,next;
      }e[1005*1005*2];
      int head[2005],match[2005],vis[2005];
      int n,m,ent=2,tim,ans,ee;
      void add(int u,int v){
      	e[ent]=(edge){v,head[u]};
      	head[u]=ent++;
      }
      bool dfs(int u){
      	for(int i=head[u];i;i=e[i].next){
      		int v=e[i].to;
      		if(vis[v]==tim) continue;
      		vis[v]=tim;
      		if(!match[v]||dfs(match[v])){
      			match[v]=u;
      			return 1;
      		}
      	}
      	return 0;
      }
      int main()
      {
      	scanf("%d%d%d",&n,&m,&ee);
      	for(int i=1,u,v;i<=ee;i++){
      		scanf("%d%d",&u,&v); 
      		if(u>n||v>m)  continue;
      		v+=n;
      		add(u,v); add(v,u);
      	}
      	for(int i=1;i<=n+m;i++){
      		tim++;
      		if(dfs(i)) ans++;
      	}
      	printf("%d",ans/2);
      	return 0;
      }
      
    • P3808 【模板】AC自动机(简单版)
      #include<cstdio>
      #include<queue>
      #include<cstring>
      #include<iostream>
      using namespace std;
      struct Trie{
      	int next,last,val;
      	int ch[30];
      }T[1000006];
      char s[1000006];
      int n,sz=0,ans;
      int idx(char ch){
      	return ch-'a';
      }
      void add(char *S){
      	int u=0,l=strlen(S);
      	for(int i=0;i<l;i++){
      		int c=idx(S[i]);
      		if(!T[u].ch[c]) T[u].ch[c]=++sz;
      		u=T[u].ch[c];
      	}
      	T[u].val++;
      }
      void build(){
      	queue<int>q;
      	for(int i=0;i<26;i++) if(T[0].ch[i]) q.push(T[0].ch[i]);
      	while(!q.empty()){
      		int u=q.front(); q.pop();
      		for(int i=0;i<26;i++){
      			if(!T[u].ch[i]) T[u].ch[i]=T[T[u].next].ch[i];
      			else{
      				int v=T[u].ch[i];
      				T[v].next=T[T[u].next].ch[i];
      				T[v].last=T[T[v].next].val?T[v].next:T[T[v].next].last;
      				q.push(v);
      			}
      		}
      	}
      }
      void get(int j){
      	if(!j||!T[j].val) return;
      	ans+=T[j].val; T[j].val=0;
      	get(T[j].last);
      }
      void match(char *S){
      	int l=strlen(S); int j=0;
      	for(int i=0;i<l;i++)
      	{
      		int c=idx(S[i]);
      		j=T[j].ch[c];
      		if(T[j].val) get(j);
      		else if(T[j].last) get(T[j].last);
      	}
      }
      int main()
      {
      	scanf("%d",&n);
      	for(int i=1;i<=n;i++){
      		scanf("%s",s);
      		add(s);
      	}
      	build(); scanf("%s",s);
      	match(s);
      	printf("%d",ans);
      	return 0;
      }
      
    • P3811 【模板】乘法逆元
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      long long inv[3000006],mod,n; 
      int main()
      {
      	scanf("%lld%lld",&n,&mod);
      	inv[1]=1;printf("%lld
      ",inv[1]);
      	for(int i=2;i<=n;i++){
      		inv[i]=( (-(mod/i)*inv[mod%i]) %mod+mod)%mod;
      		printf("%lld
      ",inv[i]);
      	}
      	return 0;
      }
      
  • 相关阅读:
    罗马数字加法实现Roman Calculator
    etymology-E
    Unreal里的输入
    Laravel框架怎样使用阿里云ACE缓存服务
    log4j和logback会互相冲突
    log4j和logback会互相冲突
    log4j和logback会互相冲突
    log4j和logback会互相冲突
    在敏捷中应用测试驱动开发
    在敏捷中应用测试驱动开发
  • 原文地址:https://www.cnblogs.com/zj75211/p/7814019.html
Copyright © 2020-2023  润新知