c++复习板子

$${\color{red}construction}$$

\(\Large{数论}\)

点击查看

GCD

点击查看
  • B4025 最大公约数

    gcd:

      #include<bits/stdc++.h>
      #define int long long
      using namespace std;
      int a,b;
      inline int read(){
      	int x=0,f=1;
      	char ch=getchar();
      	while(ch<'0'||ch>'9'){
      		if(ch=='-') f=-1;
      		else ch=getchar();
      	}
      	while(ch>='0'&&ch<='9'){
      		x=(x*10+ch-48);
      		ch=getchar();
      	}
      	return x*f;
      }
      int gcd(int a,int b) {
      	if(!b) return a;
      	return gcd(b,a%b);
      }
      signed main(){
      	a=read(),b=read();
      	cout<<gcd(a,b);
      }
      
    
  • P2613 【模板】有理数取余

    exgcd:

      #include<bits/stdc++.h>
      #define int long long
      using namespace std;
      const int mod=19260817;
      int a,b;
      int pow(int a,int b){
      	int res=1;
      	while(b){
      		if(b&1){
      			res=res*a%mod;
      		}
      		a=a*a%mod;
      		b>>=1;
      	}
      	return res;
      }
      inline int read(){
      	int x=0,f=1;
      	char ch=getchar();
      	while(ch<'0'||ch>'9'){
      		if(ch=='-') f=-1;
      		else ch=getchar();
      	}
      	while(ch>='0'&&ch<='9'){
      		x=(x*10+ch-48)%mod;
      		ch=getchar();
      	}
      	return x*f%mod;
      }
      signed main(){
      	a=read(),b=read();
      	if(!b){
      		cout<<"Angry!";
      		return 0;
      	}
      	cout<<a*pow(b,mod-2)%mod;
      }
    
  • 质因数分解

    #include<bits/stdc++.h>
    using namespace std;
    signed main(){
        int n;
        cin>>n;
        for(int i=2;i<=n;i++){
      	  if(n%i==0){
      		while(n%i==0){
      			cout<<i<<" ";
      			n/=i;
      		}
        	}
        } 
        if(n!=1){
        	cout<<n<<endl;
        }
    }
    

筛法

点击查看
  • P3383 【模板】线性筛素数

    欧拉筛:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int n,q,tot;
    int prime[7000003]; //判断质数 
    bool vis[100000004];
    void Prime_shai(int up){
      	 memset(vis,1,sizeof vis);
      	 vis[1]=0;
           for(int i=2;i<=n;i++){
             if(vis[i]){
      	    	prime[++tot]=i; //没有被筛就是质数 
      	    }
      	 for(int j=1;prime[j]*i<=n&&j<=tot;j++){
      		vis[i*prime[j]]=0; //被筛到打个标记 
      		if(!i%prime[j]) break; //如果prime[j]是i的因子,那么以后得最小质因数就不在是prime[x]而是prime[j] 
      	  }
        }
    }
    int a;
    signed main(){
    	cin>>n>>q;
    	Prime_shai(n);
      while(q--){
      	cin>>a;
      	cout<<prime[a]<<"\n";
      } 
    }
    

拉格朗日插值

点击查看
  • P4781 【模板】拉格朗日插值

    //By yueyan_WZF
    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    inline int rd(){
        int x = 0, f = 1;
        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;
    }
    const int N=2e3+20;
    const int mod=998244353;
    int n,k;
    int x[N],y[N];
    int power(int a,int b){
        int res=1;
        while(b){
            if(b&1) res=res*a%mod;
            a=a*a%mod;b>>=1;
        }
        return res;
    }
    int F(int xx){
        int ans=0;
        for(int i=1;i<=n;i++){
            int s1=1,s2=1;
            for(int j=1;j<=n;j++){
                if(j==i) continue;
                s1=s1*(xx-x[j])%mod;
                s2=s2*(x[i]-x[j])%mod;
            }
            ans=(ans+((s1*power(s2,mod-2))%mod*y[i]%mod))%mod;
        }
        return (ans%mod+mod)%mod;
    }
    signed main(){
        // freopen(".in","r",stdin);
        // freopen(".out","w",stdout);
        cin>>n>>k;
        for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
        cout<<F(k);
        return 0;
    }
    
    

莫比乌斯反演

点击查看
  • P2257 YY的GCD

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e7+15;
    int sum[N+5];
    int mu[N+5];
    int  f[N+5];
    bool vis[N+5];
    int prime[N+5];
    int cnt,n,m;
    void init(){
        mu[1]=1;
        for(int i=2;i<=N;i++){
      	  if(!vis[i]) {
      		  prime[++cnt]=i;
      		  mu[i]=-1;
      	  }
      	  for(int j=1;j<=cnt&&prime[j]*i<=N;j++){
      		  vis[i*prime[j]]=1;
      		  if(!(i%prime[j])) break;
      		  mu[i*prime[j]]=-mu[i];
      	  }
        }
        for(int i=1;i<=cnt;i++){
      	  for(int j=1;j*prime[i]<=N;j++){
      		  f[j*prime[i]]+=mu[j];
      	  }
        }
        for(int i=1;i<=N;i++) sum[i]=sum[i-1]+f[i];
    }
    int T;
    void solve(int a,int b){
        int l,r=0,ans=0;
        if(a>b) swap(a,b);
        for(l=1;l<=a;l=r+1){
      	  r=min(a/(a/l),b/(b/l));
      	  ans=ans+((a/l)*(b/l)*(sum[r]-sum[l-1]));
        }
        cout<<ans<<" \n";
    }
    signed main(){
        init();
        cin>>T;
        while(T--){
      	  cin>>n>>m;
      	  solve(n,m);
        }
    }
    

逆元

点击查看
  • P3811 【模板】模意义下的乘法逆元

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int ni[3000289];
    int main(){
    	ll n,p;
    	scanf("%lld%lld",&n,&p);
    	ni[1]=1;
    	cout<<"1"<<endl;
    	for(int i=2;i<=n;++i){
    		ni[i]=1ll*(p-p/i)*ni[p%i]%p;
    		printf("%d\n",ni[i]);
    	}
    }
    

高斯消元

点击查看
  • P3389 【模板】高斯消元法

      #include<bits/stdc++.h>
      using namespace std;
      double k[102][102];
      double ans[103];
      double Min=1e-7;
      int n; 
      signed main(){
      	cin>>n;
      	for(int i=1;i<=n;i++){
      		for(int j=1;j<=n+1;j++) cin>>k[i][j];
      	}
      	for(int i=1;i<=n;i++){
      		int id=i;
      		for(int j=i+1;j<=n;j++){
      			if(abs(k[j][i])>abs(k[id][i])) id=j;
      		}
      		//cout<<i<<" "<<id<<" "<<k[id][i]<<endl;
      		if(abs(k[id][i])<Min){	
      		//	cout<<i<<" "<<id<<" "<<k[id][i]<<endl;
      			cout<<"No Solution\n";
      			return 0;
      		}
      		swap(k[id],k[i]);
      		double t=k[i][i];
      		for(int j=i+1;j<=n+1;j++) k[i][j]/=k[i][i];
      		for(int j=i+1;j<=n;j++){
      			t=k[j][i];
      			for(int p=i;p<=n+1;p++){
      				k[j][p]-=k[i][p]*t;
      			}
      		}
      	}
      	ans[n]=k[n][n+1];
      	for(int i=n-1;i>=1;i--){
      		ans[i]=k[i][n+1];
      		for(int j=i+1;j<=n;j++){
      			ans[i]-=(k[i][j]*ans[j]);
      		}
      	}
      	for(int i=1;i<=n;i++){
      		printf("%.2lf\n",ans[i]); 
      	}
      }
    
    

整除分块

点击查看
  • P2261 [CQOI2007] 余数求和

    //By yueyan_WZF
    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    inline int rd(){
        int x = 0, f = 1;
        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 n,k;
    signed main(){
        // freopen(".in","r",stdin);
        // freopen(".out","w",stdout);
        cin>>n>>k;
        int r;
        int ans=n*k;
        for(int l=1;l<=n;l=r+1){
            if(k/l!=0) r=min(k/(k/l),n);
            else r=n;
            ans-=(k/l)*(r-l+1)*(l+r)/2;
        }
        cout<<ans;
        return 0;
    }
    

\(\Large{图论}\)

点击查看

最短路

点击查看
  • P3371 【模板】单源最短路径(弱化版)

    SPFA :

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int n,m,u,v,w,s;
    struct node{
        int to,nxt,w;
    }z[10000040]; //链式前向星
    int cnt;
    int h[1000004];
    int dis[1000004];
    int vis[1000004];
    void add(int x,int y,int w){
        z[++cnt].to=y;
        z[cnt].nxt=h[x];
        z[cnt].w=w;
        h[x]=cnt;
    }
    void SPFA(int start){
        for(int i=1;i<=n;i++) dis[i]=1e11,vis[i]=0;
        vis[start]=1;
        queue<int> p;
        dis[start]=0;
        p.push(start);
        while(!p.empty()){
            int x=p.front();
            p.pop();
            vis[x]=0;
            for(int i=h[x];i;i=z[i].nxt){
                int y=z[i].to;
                if(dis[y]>dis[x]+z[i].w){
                    dis[y]=z[i].w+dis[x];
                    if(!vis[y]){
                        vis[y]=1;
                        p.push(y);
                    }
                }
            }
        }
    }
    signed main(){
        cin>>n>>m>>s;
        for(int i=1;i<=m;i++){
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w);
        }
        SPFA(s);
        for(int i=1;i<=n;i++){
            if(dis[i]!=1e11) cout<<dis[i]<<" ";
            else cout<<"2147483647 ";
        }
    }
    
  • P4779 【模板】单源最短路径(标准版)

    迪杰斯特拉:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    typedef pair<int,int> pii;
    int n,m,u,v,w,s;
    struct node{
      int to,nxt,w;
    }z[10000040]; //链式前向星
    int cnt;
    int h[1000004];
    int dis[1000004];
    int vis[1000004];
    void add(int x,int y,int w){
        z[++cnt].to=y;
        z[cnt].nxt=h[x];
        z[cnt].w=w;
        h[x]=cnt;
    }
    void dijie(int start){
        for(int i=1;i<=n;i++) dis[i]=1e11,vis[i]=0;
        dis[start]=1;
        priority_queue<pii,vector<pii>,greater<pii> > p;
        p.push(make_pair(0,start));
        while(!p.empty()){
            int x=p.top().second;
            p.pop();
            if(vis[x]) continue;
            else{
                vis[x]=1;
                for(int i=h[x];i;i=z[i].nxt){
                    int y=z[i].to;
                    if(dis[y]>dis[x]+z[i].w){
                        dis[y]=dis[x]+z[i].w;
                        p.push(make_pair(dis[y],y));
                    }
                }
            }
        }
    }
    signed main(){
        cin>>n>>m>>s;
         for(int i=1;i<=m;i++){
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w);
        }
       dijie(s);
        for(int i=1;i<=n;i++){
            cout<<dis[i]<<" ";
        }
    }
    
  • B3647 【模板】Floyd

    Floyd:

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
      int n,m;
      cin>>n>>m;
      int a[102][102];
      for(int i=1;i<=n;i++){
      	for(int j=1;j<=n;j++){
      		a[i][j]=0x3f3f3f3f;
      		a[j][i]=0x3f3f3f3f;
      	}
      }
      for(int i=1;i<=m;i++){
      	int a1,b,c;
      	cin>>a1>>b>>c;
      	if(a[a1][b]>c){
      		a[a1][b]=c;
      	a[b][a1]=c;
      	}
      	
      }
      for(int k=1;k<=n;k++){
      	for(int i=1;i<=n;i++){
      		for(int j=1;j<=n;j++){
      			if(a[i][k]+a[k][j]<a[i][j]){
      				a[i][j]=a[i][k]+a[k][j];
      				a[j][i]=a[i][k]+a[k][j];
      			}
      			if(i==j){
      				a[i][j]=a[j][i]=0;
      			}
      		}
      	}
      }
      for(int i=1;i<=n;i++){
      	for(int j=1;j<=n;j++){
      		cout<<a[i][j]<<" ";
      	}
      	cout<<endl;
      }
    }
    
  • P1144 最短路计数

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int Mod=100003;
    typedef pair<int,int> pii;
    int cnt,n,m,x,y;
    map<int,int> mp[2000040];
    int h[3000004];
    struct node{
    	int to,nxt;
    }z[4000004];	
    void add(int x,int y){
    	z[++cnt].to=y;
    	z[cnt].nxt=h[x];
    	h[x]=cnt;
    }	
    int ans[3000003];
    int dis[3000004];
    int vis[3000004];
    void dijie(int start){
    	priority_queue<pii,vector<pii>,greater<pii> > p;
    	for(int i=1;i<=n;i++) dis[i]=1e11,vis[i]=0;
    	dis[start]=0;
    	ans[start]=1;
    	p.push({0,start});
    	while(!p.empty()){
    		int x=p.top().second;
    		p.pop();
    		if(vis[x]) continue;
    		else{
    			vis[x]=1;
    			for(int i=h[x];i;i=z[i].nxt){
    				int y=z[i].to;
    				if(dis[y]>dis[x]+1){
    					dis[y]=dis[x]+1;
    					ans[y]=ans[x];
    					p.push({dis[y],y});
    				}
    				else if(dis[y]==dis[x]+1){
    					ans[y]+=ans[x];
    					ans[y]%=Mod;
    				}
    			}
    		}
    	}
    }
    signed main(){
    	cin>>n>>m;
    	for(int i=1;i<=m;i++){
    		cin>>x>>y;
    		if(x==y) continue;
    		else{
    		// if(mp[x].count(y)) continue; //判重边
    			add(x,y);
    			add(y,x);
    			mp[x][y]=1;
    			mp[y][x]=1;
    		}
    	}
    	dijie(1);
    	for(int i=1;i<=n;i++){
    		cout<<ans[i]<<"\n";
    	}
    }
    
  • P5960 【模板】差分约束

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int n,m;
    struct node{
       int to,nxt,w;
    }z[1000004];
    int cnt;
    int h[1000004];
    void add(int x,int y,int w){
      z[++cnt].to=y;
      z[cnt].w=w;
      z[cnt].nxt=h[x];
      h[x]=cnt;
    }
    int dis[1000004];
    int vis[1000004];
    int tot[1000004];
    bool SPFA(int s){
      memset(dis,0x3f3f3f,sizeof(dis));
      vis[s]=1;
      dis[s]=0;
      queue<int> p;
      p.push(s);
     while(!p.empty()){
           int x=p.front();
          p.pop();
          vis[x]=0;
          for(int i=h[x];i;i=z[i].nxt){
              int y=z[i].to;
              if(dis[y]>dis[x]+z[i].w){
                  dis[y]=dis[x]+z[i].w;
                  if(!vis[y]){
                      tot[y]++;
                      vis[y]=1;
                      if(tot[y]==n+1) return false;
                      p.push(y);
                  }
              }
          }
      }
      return true;
    }
    signed main(){
      cin>>n>>m;
      for(int i=1;i<=m;i++){
          int a,b,c;
          scanf("%lld%lld%lld",&a,&b,&c);
          add(b,a,c);
      }
      for(int i=1;i<=n;i++) add(0,i,0);
      if(SPFA(0)){
          for(int i=1;i<=n;i++){
              cout<<dis[i]<<" ";
          }
      }
      else{
          cout<<"NO";
      }
    }
    
  • 同余最短路ARC084B

    #include<bits/stdc++.h>
    using namespace std;
    int K;
    struct node{
        int to,nxt,w;
    }z[2000004];
    int h[2000004];
    int cnt;
    void add(int x,int y,int w){
        z[++cnt].to=y;
        z[cnt].nxt=h[x];
        h[x]=cnt;
        z[cnt].w=w;
    }
    int dis[10000004];
    int vis[2000004];
    typedef pair<int,int> pii;
    signed main(){
        cin>>K;
        for(int i=1;i<=K;i++){
            for(int j=0;j<=9;j++){
                add(i,((i-1)*10+j)%K+1,j);
            }
        }
        for(int i=1;i<=9;i=i+1){
            add(0,i+1,i);
        }
        int s=0;
        memset(dis,0x3f3f3f,sizeof dis);
        dis[s]=0;
        priority_queue<pii,vector<pii>,greater<pii> > p;
        p.push({0,s});
        while(!p.empty()){
            int x=p.top().second;
            p.pop();
            if(vis[x]) continue;
            vis[x]=1;
           // cout<<x<<endl;
            for(int i=h[x];i;i=z[i].nxt){
                int y=z[i].to;
                if(dis[y]>dis[x]+z[i].w){
                    dis[y]=dis[x]+z[i].w;
                    p.push({dis[y],y});
                }
            }
        }
        cout<<dis[1];
    }
    

网络流

点击查看
  • 最小割 狼抓兔子

    (最短路求法)

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int n,m;
    struct Edge{
        int to,nxt,w;
    }z[50000004];
    int cnt;
    int h[20000005];
    void add(int x,int y,int w){
        z[++cnt].to=y;
        z[cnt].nxt=h[x];
        h[x]=cnt;
        z[cnt].w=w;
    }
    int  S=0,T;
    void Init(){
        int w;
        cin>>n>>m;
        T=(n-1)*(m-1)*2+1;
        for(int i=1;i<m;i++){
            cin>>w;
            add(S,i,w);
        }
        for(int i=2;i<n;i++){
            int lst=(i-1)*(m-1)*2;
            for(int j=1;j<m;j++){
                cin>>w;
                int a=lst-(m-1-j);
            //    cout<<a<<" "<<a+(m-1)<<endl;
                add(a,a+(m-1),w);
                add(a+(m-1),a,w);
            }
        }
        for(int i=1;i<m;i++){
            cin>>w;
            add(T-1-(m-1-i),T,w);
         ///   cout<<T-1-(m-1-i)<<" ";
        }
        //puts(" ");
        for(int i=1;i<n;i++){
            cin>>w;
            add((i-1)*(m-1)*2+(m-1)+1,T,w);
            //cout<<endl<<(i-1)*(m-1)*2+(m-1)+1<<endl;
            for(int j=2;j<m;j++){
                cin>>w;
                add((i-1)*(m-1)*2+j-1,(i-1)*(m-1)*2+j-1+m,w);
                add((i-1)*(m-1)*2+j-1+m,(i-1)*(m-1)*2+j-1,w);
              //  cout<<endl<<(i-1)*(m-1)*2+j-1<<" "<<(i-1)*(m-1)*2+j-1+m<<endl;
            }
            cin>>w;
            add(S,(i-1)*(m-1)*2+(m-1),w);
         //   cout<<endl<<(i-1)*(m-1)*2+(m-1)<<endl;
        }
     //  puts("o");
        for(int i=1;i<n;i++){
            for(int j=1;j<m;j++){
                cin>>w;
                add((i-1)*(m-1)*2+j,(i-1)*(m-1)*2+j+(m-1),w);
                add((i-1)*(m-1)*2+j+(m-1),(i-1)*(m-1)*2+j,w);
               // cout<<(i-1)*(m-1)*2+j<<" "<<(i-1)*(m-1)*2+j+(m-1)<<endl;
            }
        }
    }
    typedef pair<int,int> pii;
    int vis[20000004];
    int dis[20000004];
    priority_queue<pii,vector<pii>,greater<pii> > p;
    void Dijie(){
        for(int i=0;i<=T;i++) dis[i]=1e18;
        dis[S]=0;
        p.push({0,S});
        while(!p.empty()){
            int x=p.top().second;
            p.pop();
            if(vis[x]) continue;
            vis[x]=1;
            for(int i=h[x];i;i=z[i].nxt){
                int y=z[i].to;
                if(dis[y]>dis[x]+z[i].w){
                    dis[y]=dis[x]+z[i].w;
                    p.push({dis[y],y});
                }
            }
        }
    }
    signed main(){
        Init();
        Dijie();
        cout<<dis[T];
    }
    
  • 最小割最大流模板 P3376

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int inf=1e9;
    int n,m,s,t;
    int u,v,w;
    int h[2000004];
    struct node{
    	int to,nxt,w;
    }z[2000004];
    int dis[2000004];
    int cnt=1;
    int cur[2000004];
    void add(int a,int b,int w){
    	z[++cnt].to=b;
    	z[cnt].nxt=h[a];
    	h[a]=cnt;
    	z[cnt].w=w;
    	z[++cnt].to=a;
    	z[cnt].nxt=h[b];
    	h[b]=cnt;
    	z[cnt].w=0;
    }
    bool bfs(){
    	for(int i=1;i<=n;i++) dis[i]=0;
    	queue<int> p;
    	p.push(s);
    	dis[s]=1;
    	while(!p.empty()){
    		int x=p.front();
    		p.pop();
    		for(int i=h[x];i;i=z[i].nxt){
    			int y=z[i].to;
    			if(z[i].w&&!dis[y]){
    				p.push(y);
    				dis[y]=dis[x]+1;
    				if(y==t) return 1;
    			}
    		}
    	}
    	return 0;
    }
    int dfs(int x,int flow){
    	if(x==t) return flow;
    	int res=flow;
    	for(int i=cur[x];i&&res;i=z[i].nxt){
    		int y=z[i].to;
    		cur[x]=i;
    		if(dis[y]==dis[x]+1&&z[i].w){
    			int k=dfs(y,min(res,z[i].w));
    			if(!k) dis[y]=0;
    			z[i].w-=k;
    			z[i^1].w+=k;
    			res-=k;
    		}
    	}
    	return flow-res;
    }
    signed main(){
    	cin>>n>>m>>s>>t;
    	for(int i=1;i<=m;i++){
    		cin>>u>>v>>w;
    		add(u,v,w);
    	}
    	int flo=0,maxx=0;
    	while(bfs()){
    		for(int i=1;i<=n;i++) cur[i]=h[i];
    		while(flo=dfs(s,(1<<29))){
    			maxx+=flo;
    		}
    	}
    	cout<<maxx;
    }
    
    
  • 最小费用最大流 P3381

    (迪杰斯特拉)

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,s,t;
    int u,v,w,c;
    int cnt=1;
    int head[1000004];
    int h[1000004];
    int cur[1000004];
    struct node{
    	int to,nxt,w,c;
    }z[2000004];
    void add(int x,int y,int w,int c){
    	z[++cnt].to=y;
    	z[cnt].nxt=head[x];
    	head[x]=cnt;
    	z[cnt].c=c;
    	z[cnt].w=w;
    	z[++cnt].to=x;
    	z[cnt].nxt=head[y];
    	head[y]=cnt;
    	z[cnt].w=0;
    	z[cnt].c=-c;
    }
    bool vis[1000004];
    int dis[1000004];
    
    void SPFA(){
    	memset(h,0x3f3f3f3f,sizeof h);
    	queue<int> p;
    	p.push(s);
    	vis[s]=1;
    	while(!p.empty()){
    		int x=p.front();
    		p.pop();
    		vis[x]=0;
    		for(int i=head[x];i;i=z[i].nxt){
    			int y=z[i].to;
    			if(z[i].w&&h[y]>h[x]+z[i].c){
    				h[y]=h[x]+z[i].c;
    				if(!vis[y]){
    					vis[y]=1;
    					p.push(y);
    				}
    			}
    		}
    	}
    }
    typedef pair<int,int> pii;
    int ans1,ans2;
    const int inf=0x3f3f3f3f;
    bool dijie(){
    	memset(dis,inf,sizeof dis);
    	memset(vis,0,sizeof vis);
    	priority_queue<pii,vector<pii>,greater<pii> > p;
    	dis[s]=0;
    	p.push({0,s});
    	while(!p.empty()){
    		int x=p.top().second;
    		p.pop();
    		if(vis[x]) continue;
    		vis[x]=1;
    		for(int i=head[x];i;i=z[i].nxt){
    			int y=z[i].to;
    			if(z[i].w&&dis[y]>dis[x]+z[i].c+h[x]-h[y]){
    				dis[y]=dis[x]+h[x]-h[y]+z[i].c;
    				p.push({dis[y],y});
    			}
    		}
    	}
    	return dis[t]!=inf;
    }
    int dfs(int x,int flow){
    	int res=flow;
    	if(x==t) return flow;
    	vis[x]=1;
    	for(int i=cur[x];i;i=z[i].nxt){
    		cur[x]=i;
    		int y=z[i].to;
    		if(z[i].w&&h[y]==h[x]+z[i].c&&!vis[y]){
    			int k=dfs(y,min(res,z[i].w));
    			z[i].w-=k;
    			z[i^1].w+=k;
    			res-=k;
    			ans2+=k*z[i].c;
    			if(!res) break;
    		}
    	}
    	vis[x]=0;
    	return flow-res;
    }
    signed main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>m>>s>>t;
    	for(int i=1;i<=m;i++){
    		cin>>u>>v>>w>>c;
    		add(u,v,w,c);
    	}
    	SPFA();
    	while(dijie()){ 
    		for(int i=1;i<=n;i++) cur[i]=head[i],vis[i]=0,h[i]+=dis[i];
    		ans1+=dfs(s,inf);
    	}
    	cout<<ans1<<" "<<ans2<<endl;
    }
    

    (SPFA)

    #include<bits/stdc++.h>
    using namespace std;
    struct node{
    	int nxt,to,w,dis;
    }z[100003];
    int minncost,maxxflow;
    int s,t,e;
    int h[1000003];
    int pre[1000003];
    int last[1000003];
    int flow[1000003];
    int dis[1000003];
    int vis[1000003];
    int cnt=1;
    void add(int u,int v,int w,int dis){
    	cnt++;
    	z[cnt].to=v;
    	z[cnt].nxt=h[u];
    	z[cnt].dis=dis;
    	z[cnt].w=w;
    	h[u]=cnt;
    }
    bool SPFA(){
    	memset(dis,0x7f7f7f7f,sizeof dis);
    	memset(vis,0,sizeof(vis));
    	memset(flow,0x7f7f7f7f,sizeof flow);
    	dis[s]=0;
    	vis[s]=1;
    	pre[e]=-1;
    	queue<int> p;
    	p.push(s);
    	while(!p.empty()){
    		int x=p.front();
    		p.pop();
    		vis[x]=0;
    		for(int i=h[x];i!=-1;i=z[i].nxt){
    			int y=z[i].to;
    			int w=z[i].dis;
    			if(dis[y]>dis[x]+w&&z[i].w){
    				pre[y]=x;
    				last[y]=i;
    				flow[y]=min(flow[x],z[i].w);
    				dis[y]=dis[x]+w;
    				if(!vis[y]){
    					vis[y]=1;
    					p.push(y);
    				}
    			}
    		}
    	}
    	if(dis[e]!=0x7f7f7f7f)return 1;
    	return 0;
    }
    void MCMF(){
    	while(SPFA()){
    		int u=e;
    		maxxflow+=flow[u];
    		minncost+=flow[u]*dis[u];
    		while(u!=s){
    			z[last[u]].w-=flow[e];
    			z[last[u]^1].w+=flow[e];
    			u=pre[u]; 
    		}
    	}
    }
    int main(){
    	int n,m;
    	scanf("%d%d%d%d",&n,&m,&s,&e);
    	for(int i=1;i<=n;i++) h[i]=-1;
    	for(int i=1;i<=m;i++){
    		int u,v,f,w;
    		scanf("%d%d%d%d",&u,&v,&f,&w);
    		add(u,v,f,w);
    		add(v,u,0,-w);
    	}
    	MCMF();
    	cout<<maxxflow<<" "<<minncost;
    }
    
  • 最小路径覆盖P2764

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    int x,y;
    struct node{
    	int to,nxt,w;
    }z[20000004];
    int cnt=1;
    int h[10000004];
    int s,t;
    int dis[10000004];
    int cur[10000004];
    void add(int x,int y,int w){
    	z[++cnt].to=y;
    	z[cnt].nxt=h[x];
    	h[x]=cnt;
    	z[cnt].w=w;
    	z[++cnt].to=x;
    	z[cnt].nxt=h[y];
    	h[y]=cnt;
    	z[cnt].w=0;
    }
    bool BFS(){
    	for(int i=1;i<=t;i++) dis[i]=0;
    	queue<int> p;
    	p.push(s);
    	dis[s]=1;
    	while(!p.empty()){
    		int x=p.front();
    		p.pop();
    		for(int i=h[x];i;i=z[i].nxt){
    			int y=z[i].to;
    			if(z[i].w&&!dis[y]){
    				//cout<<"o\n";
    				p.push(y);
    				dis[y]=dis[x]+1;
    				if(y==t) return 1;
    			}
    		}
    	}
    	return 0;
    }
    int maxx;
    int dfs(int x,int flow){
    	if(x==t) return flow;
    	int res=flow;
    	for(int i=cur[x];i&&res;i=z[i].nxt){
    		int y=z[i].to;
    		cur[x]=i;
    		if(z[i].w&&dis[y]==dis[x]+1){
    			int k=dfs(y,min(res,z[i].w));
    			if(!k) dis[y]=0;
    			z[i].w-=k;
    			z[i^1].w+=k;
    			res-=k;
    		}
    	}
    	return flow-res;
    }
    int flo;
    void Dinic(){
    	while(BFS()){
    		for(int i=0;i<=t;i++) cur[i]=h[i];
    		while(flo=dfs(s,(1<<29))) maxx+=flo;
    	}
    }
    int fa[10000004];
    int find(int x){
    	if(x==fa[x]) return x;
    	else return fa[x]=find(fa[x]);
    }
    void merge(int x,int y){
    	int fx=find(fa[x]);
    	int fy=find(fa[y]);
    	if(fx!=fy) fa[fx]=fy;
    }
    
    signed main(){
    	cin>>n>>m;
    	for(int i=1;i<=m;i++){
    		cin>>x>>y;
    		add(x,y+n,1);
    	}
    	s=0,t=(n<<1)+1;
    	for(int i=1;i<=n;i++){
    		add(s,i,1);
    		add(i+n,t,1);
    	}
    	Dinic();
    	int ans=n-maxx;
    	for(int i=1;i<=t;i++) fa[i]=i;
    	for(int i=1;i<=n;i++){
    		for(int j=h[i];j;j=z[j].nxt){
    			int y=z[j].to;
    			if(!z[j].w&&y-n<=n&&y){
    				merge(i,y-n);
    			}
    		}
    	}
    
    	for(int i=n;i;i--){
    		bool flag=0;
    		for(int j=1;j<=n;j++){
    			if(find(j)==i){
    				cout<<j<<" ";
    				flag=1;
    			}
    		}if(flag) cout<<"\n";
    	}
    	cout<<ans<<"\n";
    }
    

欧拉回路

点击查看
  • 欧拉回路

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    int t;
    int n, m;
    int a, b;
    int in[200004];
    int out[200004];
    struct node {
    	int to, nxt, id;
    } z[4000004];
    int sum[4000004];
    int h[2000004];
    int cnt;
    void add(int x, int y, int id) {
    	z[++cnt].to = y;
    	z[cnt].nxt = h[x];
    	h[x] = cnt;
    	z[cnt].id = id;
    }
    int num;
    int ans[200004];
    bool vis[200004];
    typedef pair<int, int> pii;
    vector<pii> v[200004];
    void dfs(int x) {
    	for (int &i = h[x]; i; i = z[i].nxt) {
    		int y = z[i].to;
    		int id = z[i].id;
    
    		if (vis[abs(id)])
    			continue;
    
    		vis[abs(id)] = 1;
    		dfs(y);
    		ans[++num] = id;
    	}
    
    }
    bool flag = 0;
    bool check() {
    	int s = 1;
    	for (int i = 1; i <= n; i++) {
    		if (t == 1) {
    			if ((in[i] + out[i]) & 1)
    				return 0;
    
    			if (in[i] + out[i])
    				s = i;
    		} else {
    			if (in[i] != out[i])
    				return 0;
    
    			if (in[i])
    				s = i;
    		}
    	}
    	dfs(s);
    	if (num < m)
    		return 0;
    	return 1;
    }
    signed main() {
    	cin >> t;
    	cin >> n >> m;
    	for (int i = 1; i <= m; i++) {
    		cin >> a >> b;
    		add(a, b, i);
    		if (t == 1)
    			add(b, a, -i);
    		in[b]++;
    		out[a]++;
    	}
    	if (!check()) {
    		cout << "NO";
    		return 0;
    	}
    	cout << "YES\n";
    	for (int i = num; i >= 1; i--)
    		cout << ans[i] << " ";
    }
    

\(\Large{树论}\)

点击查看

树的直径

点击查看
  • B4016 树的直径

    #include<bits/stdc++.h>
    using namespace std;
    int n,a,b;
    struct node{
      int to,nxt;
    }z[1000004];
    int cnt;
    int h[1000040];
    void add(int x,int y){
      z[++cnt].to=y;
      z[cnt].nxt=h[x];
      h[x]=cnt;
    }
    int id,maxx;
    int dis[2000004];
    void dfs(int x,int fa){
      if(dis[x]>maxx){
          maxx=dis[x];
          id=x;
      }
      for(int i=h[x];i;i=z[i].nxt){
          int y=z[i].to;
          if(y==fa) continue;
          else{
              dis[y]=dis[x]+1;
              dfs(y,x);
          }
      }
    }
    int main(){
      cin>>n;
      for(int i=1;i<n;i++){
          cin>>a>>b;
          add(a,b);
          add(b,a);
      }
      dfs(1,0);
      memset(dis,0,sizeof dis);
      maxx=0;
      dfs(id,0);
      cout<<maxx;
    } 
    

LCA

点击查看
  • P3379 【模板】最近公共祖先(LCA)

    倍增:

    	#include<bits/stdc++.h>
    using namespace std;
    int n,m,s;
    int f[500005][21];
    int d[500002];
    vector<int> g[5000070];
    void dfs(int x,int fa){
    	f[x][0]=fa;
    	d[x]=d[fa]+1;
    	for(int i=0;i<g[x].size();i++){
    		if(g[x][i]==fa) continue;
    		dfs(g[x][i],x);
    	}
    }
    void gh(){
    	for(int j=1;j<=20;j++){
    		for(int i=1;i<=n;i++){
    			f[i][j]=f[f[i][j-1]][j-1];
    		}
    	}
    }
    int lca(int x,int y){
    	if(d[x]<d[y]) swap(x,y);
    	for(int i=20;i>=0;i--){
    		if(d[f[x][i]]>=d[y]) x=f[x][i];
    	}
    	if(x==y){
    		return y;
    	}
       for(int i=20;i>=0;i--){
    		if(f[x][i] != f[y][i])
    		x = f[x][i], y = f[y][i];
    	}
    
    
    	return  f[x][0];
    }
    int main(){
    	cin>>n>>m>>s;
    	for(int i=1;i<n;i++){
    		int x,y;
    		cin>>x>>y;
    		g[x].push_back(y);
    		g[y].push_back(x);
    	}
    	dfs(s,0);
    	gh();
    	for(int i=1;i<=m;i++){
    		int a,b;
    		cin>>a>>b;
    		cout<<lca(a,b)<<endl;
    	}
    }
    

    树剖:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,s;
    int cnt;
    struct node{
    	int to,nxt;
    }z[1200000];
    struct lian{
    	int fa,top,num,son,maxxson,dep;
    }l[500006];
    int h[500004];
    void add(int x,int y){
    	z[++cnt].to=y;
    	z[cnt].nxt=h[x];
    	h[x]=cnt;
    }
    void dfs(int x,int fa){
    	l[x].fa=fa;
    	l[x].dep=l[fa].dep+1;
    	l[x].son=1;
    	l[l[x].maxxson].son=-1;
    	for(int i=h[x];i;i=z[i].nxt){
    		int y=z[i].to;
    		if(y==fa) continue;
    		dfs(y,x);
    		l[x].son+=l[y].son;
    		if(l[y].son>l[l[x].maxxson].son){
    			l[x].maxxson=y;
    			l[l[x].maxxson].son=l[y].son;
    		}
    	}
    }
    int id;
    void dfs1(int x,int fa,int top){
    	l[x].top=top;
    	l[x].num=++id;
    	if(!l[x].maxxson) return ;
    	dfs1(l[x].maxxson,x,top);
    	for(int i=h[x];i;i=z[i].nxt){
    		int y=z[i].to;
    		if(y==fa||y==l[x].maxxson) continue;
    		else{
    			dfs1(y,x,y);
    		}
    	}
    }
    int lca(int a,int b){
    	while(l[a].top!=l[b].top){
    		if(l[l[a].top].dep<l[l[b].top].dep) swap(a,b);
    		a=l[l[a].top].fa;
    	}
    	if(l[a].dep>l[b].dep){
    		swap(a,b);
    	}
    	return a;
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&s);
    	for(int i=1;i<n;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		add(y,x);
    	}
    	l[0].dep=0;
    	dfs(s,0);
    	dfs1(s,0,s);
    	while(m--){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		printf("%d\n",lca(x,y));
    	}
    }
    
    

\(\Large{数据结构}\)

点击查看

树链剖分

点击查看
  • P3384 【模板】重链剖分/树链剖分

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    struct node{
    	int to,nxt;
    }z[N];
    struct tree{
    	int l,r,lazy,sum;
    }t[4*N];
    struct good{
    	int w,fa,top,id,d,son,maxson;
    }l[N];
    int n,m,root,mod,ans;
    int h[N];
    int a[N];
    int w[N];
    int cnt,res;
    void add(int x,int y){
    	cnt++;
    	z[cnt].to=y;
    	z[cnt].nxt=h[x];
    	h[x]=cnt;
    }
    void dfs1(int x,int fa,int dis){
    	l[x].son=1;
    	l[x].fa=fa;
    	l[x].d=dis;
    	l[l[x].maxson].son=-1;
    	for(int i=h[x];i;i=z[i].nxt){
    		int y=z[i].to;
    		if(y==fa) continue;
    		dfs1(y,x,dis+1);
    		l[x].son+=l[y].son;
    		if(l[y].son>l[l[x].maxson].son)l[x].maxson=y,l[l[x].maxson].son=l[y].son;
    	}
    }
    void dfs2(int x,int topf){
    	l[x].id=++cnt;
    	w[cnt]=a[x];
    	l[x].top=topf;
    	if(!l[x].maxson)return;
    	dfs2(l[x].maxson,topf);
    	for(int i=h[x];i;i=z[i].nxt){
    		int y=z[i].to;
    		if(y==l[x].fa||y==l[x].maxson)continue;
    		dfs2(y,y);
    	}
    }
    void build(int l,int r,int p){
    	t[p].l=l;
    	t[p].r=r;
    	if(l==r){
    		t[p].sum=w[l];
    		t[p].sum%=mod;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(l,mid,p*2);
    	build(mid+1,r,p*2+1);
    	t[p].sum=t[p*2].sum+t[p*2+1].sum;
    	t[p].sum%=mod;
    }
    void lazzy(int x){
    	if(t[x].lazy){
    		t[x*2].sum+=t[x].lazy*(t[x*2].r-t[x*2].l+1);
    		t[x*2+1].sum+=t[x].lazy*(t[x*2+1].r-t[x*2+1].l+1);
    		t[x*2].lazy+=t[x].lazy;
    		t[x*2+1].lazy+=t[x].lazy;
    		t[x*2].sum%=mod;
    		t[x*2+1].sum%=mod;
    		t[x*2+1].lazy%=mod;
    		t[x*2].lazy%=mod; 
    		t[x].lazy=0;
    	}
    }
    int qury(int L,int R,int p){
    	int res=0;
    	if(t[p].l>=L&&t[p].r<=R) {
    		return t[p].sum;
    	}
    	lazzy(p);
    	int mid=t[p].l+t[p].r>>1;
    	if(L<=mid){
    		res+=qury(L,R,p*2);
    	}
    	if(R>mid){
    		res+=qury(L,R,p*2+1);
    	}
    	return res%mod;
    }
    void chan(int l,int r,int k,int p){
    	if(t[p].l>=l&&t[p].r<=r){
    		t[p].lazy+=k;
    		t[p].sum+=k*(t[p].r-t[p].l+1);
    		t[p].sum%=mod;
    		t[p].lazy%=mod;
    		return ;
    	}
    	lazzy(p);
    	int mid=t[p].r+t[p].l>>1;
    	if(l<=mid){
    		chan(l,r,k,p*2);
    	}
    	if(r>mid){
    		chan(l,r,k,p*2+1);
    	}
    	t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
    }
    int find(int x,int y){
    	int ans=0;
    	while(l[x].top!=l[y].top){
    		if(l[l[x].top].d<l[l[y].top].d){
    		}
    		ans+=qury(l[l[x].top].id,l[x].id,1);
    		ans=ans%mod;
    		x=l[l[x].top].fa;
    	}
    	if(l[x].d>l[y].d) swap(x,y);
    	ans+=qury(l[x].id,l[y].id,1);
    	return ans%mod;
    }
    void geng2(int x,int z){
    	chan(l[x].id,l[x].id+l[x].son-1,z,1);
    }
    void geng(int x,int y,int z){
    	z=z%mod;
    	while(l[x].top!=l[y].top){
    		if(l[l[x].top].d<l[l[y].top].d){
    			swap(x,y);
    		}
    		chan(l[l[x].top].id,l[x].id,z,1);
    		x=l[l[x].top].fa;
    	}
    	if(l[x].d>l[y].d){
    		swap(x,y);
    	}
    	chan(l[x].id,l[y].id,z,1);
    }
    int find2(int x){
    	ans=0;
    	ans=qury(l[x].id,l[x].id+l[x].son-1,1);
    	return ans%mod;
    }
    int main(){
    	scanf("%d%d%d%d",&n,&m,&root,&mod);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    		a[i]%=mod;
    	}
    	for(int i=1;i<=n-1;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		add(y,x); 
    	}
    	dfs1(root,0,1);
    	cnt=0;
    	dfs2(root,root);
    	build(1,n,1);
    	for(int i=1;i<=m;i++){
    		int opt;
    		scanf("%d",&opt);
    		if(opt==1){
    			int x,y,z;
    			scanf("%d%d%d",&x,&y,&z);
    			geng(x,y,z);
    		}
    		if(opt==2){
    			int x,y;
    			scanf("%d%d",&x,&y);
    			printf("%d\n",find(x,y));
    		}
    		if(opt==3){
    			int x,z;
    			scanf("%d%d",&x,&z);
    			geng2(x,z);
    		}
    		if(opt==4){
    			int x;
    			scanf("%d",&x);
    			printf("%d\n",find2(x));
    		}
    	}
    }
    

\(\Large{字符串}\)

点击查看

Z 函数

点击查看
  • P5410 【模板】扩展 KMP/exKMP(Z 函数)

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2e7+10;
    char a[N],b[N];
    int ans;
    int z[N];
    int p[N];
    signed main(){
    	ios::sync_with_stdio(false);
    	cin>>(a+1)>>(b+1);
    	int l=0,r=0;
    	z[1]=strlen(b+1);
    	for(int i=2;i<=strlen(b+1);i++){
    		if(i<r) z[i]=min(z[i-l+1],r-i+1);
    		while(i+z[i]<=strlen(b+1)&&b[i+z[i]]==b[z[i]+1]) {
    			z[i]++;
    		}
    		if(r<i+z[i]-1){
    			r=i+z[i]-1;
    			l=i;
    		}
    	}
    	for(int i=1;i<=strlen(b+1);i++){
    		ans=ans^(i*(z[i]+1));
    	}
    	cout<<ans<<endl;
    	l=0,r=0;
    	for(int i=1;i<=strlen(a+1);i++){
    		if(i<r) p[i]=min(z[i-l+1],r-i+1);
    		while(i+p[i]<=strlen(a+1)&&a[i+p[i]]==b[p[i]+1]) {
    			p[i]++;
    		}
    		if(r<i+p[i]-1){
    			r=i+p[i]-1;
    			l=i;
    		}
    	}
    	ans=0;
    	for(int i=1;i<=strlen(a+1);i++){
    		ans^=(i*(p[i]+1));
    	}
    	cout<<ans;
    }
    

AC 自动机

点击查看
  • P5357 【模板】AC 自动机

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    const int N=200007;
    string s;
    int fail[N];
    int num;
    int trie[N][30];
    int End[N];
    int in[N];
    vector<int> v[N];
    int val[N];
    void insert(int id){
    	int p=0;
    	for(int i=0;i<s.size();i++){
    		if(!trie[p][s[i]-'a']) trie[p][s[i]-'a']=++num;
    		p=trie[p][s[i]-'a'];
    	}
    	End[id]=p;
    }
    void build(){
    	queue<int> p;
    	for(int i=0;i<26;i++){
    		if(trie[0][i]){
    			fail[trie[0][i]]=0;
    			p.push(trie[0][i]);
    		}
    	}
    	while(!p.empty()){
    		int x=p.front();
    		p.pop();
    		for(int i=0;i<26;i++){
    			if(trie[x][i]){
    				fail[trie[x][i]]=trie[fail[x]][i];
    				p.push(trie[x][i]);
    			}
    			else{
    				trie[x][i]=trie[fail[x]][i];
    			}
    		}
    	}
    }
    void ACZDJ(){
    	int p=0;
    	for(int i=0;i<s.size();i++){
    		p=trie[p][s[i]-'a'];
    		val[p]++;
    	}
    	return ;
    }
    signed main(){
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>s;
    		insert(i);
    	}
    	build();
    	for(int i=1;i<=num;i++){
    		v[i].push_back(fail[i]);
    		in[fail[i]]++;
    	}
    	cin>>s;
    	ACZDJ();
    	queue<int> Q;
    	for(int i=0;i<=num;i++){
    		if(!in[i]) Q.push(i);;
    	}
    	while(!Q.empty()){
    		int x=Q.front();
    		Q.pop();
    		for(int i=0;i<v[x].size();i++){
    			int y=v[x][i];
    			in[y]--;
    			val[y]+=val[x];
    			if(!in[y]) Q.push(y);
    		}
    	}
    	for(int i=1;i<=n;i++) {
    		cout<<val[End[i]]<<"\n";
    	}
    }
    

后缀数组 SA

点击查看
  • P3809 【模板】后缀排序

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+10;
    char s[N];
    int m,p,n;
    int rk[N<<1],sa[N<<1],ork[N<<1],id[N],cnt[N];
    signed main(){
        cin>>(s+1);
        n=strlen(s+1);
        m=127;
        for(int i=1;i<=n;i++) ++cnt[rk[i]=s[i]];
        for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
        for(int i=n;i>=1;i--) sa[cnt[rk[i]]--]=i;
        memcpy(ork+1,rk+1,n*sizeof(int));
        for(int i=1;i<=n;i++){
            if(ork[sa[i]]==ork[sa[i-1]]) rk[sa[i]]=p;
            else rk[sa[i]]=++p;
        }
        for(int w=1;w<n;w<<=1,m=n){
        //    int cur=0;
            memset(cnt,0,sizeof cnt);
            memcpy(id+1,sa+1,n*sizeof(int));
            for(int i=1;i<=n;i++) ++cnt[rk[id[i]+w]];
            for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
            for(int i=n;i>=1;i--) sa[cnt[rk[id[i]+w]]--]=id[i];
            memset(cnt,0,sizeof cnt);
            memcpy(id+1,sa+1,n*sizeof(int));
            for(int i=1;i<=n;i++) ++cnt[rk[id[i]]];
            for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
            for(int i=n;i>=1;i--) sa[cnt[rk[id[i]]]--]=id[i];
            memcpy(ork+1,rk+1,n*sizeof(int));
            p=0;
            for(int i=1;i<=n;i++){
                if(ork[sa[i]]==ork[sa[i-1]]&&ork[sa[i]+w]==ork[sa[i-1]+w]) rk[sa[i]]=p;
                else rk[sa[i]]=++p;
            }
        }
        for(int i=1;i<=n;i++) cout<<sa[i]<<" ";
    }
    
posted @ 2025-02-28 22:15  Distant_Cloud  阅读(24)  评论(0)    收藏  举报