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; }
树的重心
点击查看
-
P1395 会议
#include<bits/stdc++.h> using namespace std; const int N=2e5; vector<int> v[N]; int n,w,u,vv; int siz[N]; int dp[N]; int dep[N]; int bg; void init(int x,int fa){ dep[x]=dep[fa]+1; siz[x]=1; for(auto y:v[x]){ if(y==fa) continue; init(y,x); siz[x]+=siz[y]; } } void dfs(int x,int fa){ if(x!=1) dp[x]=dp[fa]+n-2*siz[x]; else dp[x]=bg; for(auto y:v[x]){ if(y==fa) continue; dfs(y,x); } } signed main(){ cin>>n; for(int i=1;i<n;i++){ cin>>u>>vv; v[u].push_back(vv),v[vv].push_back(u); } dep[0]=-1; init(1,0); for(int i=1;i<=n;i++) bg+=dep[i]; dfs(1,0); int minn=1e9,id; for(int i=1;i<=n;i++){ if(minn>dp[i]){ minn=dp[i]; id=i; } } cout<<id<<" "<<minn; }
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)); } }dfs序:
#include<bits/stdc++.h> using namespace std; const int N=1e6+20; int rt; int n,m,x,y,a,b; struct LCA{ struct node{ int to,nxt; }z[N]; int f[N],h[N],dfn[N],st[31][N],dep[N]; int tot=0,res=0; void add(int x,int y){ z[++tot].to=y; z[tot].nxt=h[x]; h[x]=tot; } void dfs(int x,int fa){ f[x]=fa; dfn[x]=++res; dep[x]=dep[fa]+1; st[0][res]=x; for(int i=h[x],y;i;i=z[i].nxt){ y=z[i].to; if(y==fa) continue; dfs(y,x); } } int Min(int x,int y){ return (dep[x]<dep[y])?x:y; } void init(){ dfs(rt,0); for(int i=1;i<=20;i++){ for(int j=1;j<=n-(1<<i)+1;j++){ st[i][j]=Min(st[i-1][j],st[i-1][j+(1<<(i-1))]); } } } int getlca(int x,int y){ if(x==y) return x; if((x=dfn[x])>(y=dfn[y])) swap(x,y); int t=__lg(y-x++); return f[Min(st[t][x],st[t][y-(1<<t)+1])]; } }lca; signed main(){ cin>>n>>m>>rt; for(int i=1;i<n;i++){ cin>>x>>y; lca.add(x,y),lca.add(y,x); } lca.init(); for(int i=1;i<=m;i++){ cin>>a>>b; cout<<lca.getlca(a,b)<<"\n"; } }
\(\Large{数据结构}\)
点击查看
树状数组
点击查看
-
P3368 【模板】树状数组 2
#include<bits/stdc++.h> using namespace std; const int N=5e5+20; int tr[N],a[N]; inline int lowbit(int x){ return x&(-x);} void add(int x,int k){ for(;x<N;x+=lowbit(x)) tr[x]+=k; } int query(int x){ int ans=0; for(;x>0;x-=lowbit(x)) ans+=tr[x]; return ans; } int opt,n,m,l,r,k; signed main(){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=m;i++){ cin>>opt; if(opt==1){ cin>>l>>r>>k; add(l,k),add(r+1,-k); } else { cin>>l; cout<<query(l)+a[l]<<"\n"; } } } -
P3374 【模板】树状数组 1
#include<bits/stdc++.h> using namespace std; const int N=5e5+20; int tr[N],a[N]; inline int lowbit(int x){ return x&(-x);} void add(int x,int k){ for(;x<N;x+=lowbit(x)) tr[x]+=k; } int query(int x){ int ans=0; for(;x>0;x-=lowbit(x)) ans+=tr[x]; return ans; } int opt,n,m,l,r,k; signed main(){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i],add(i,a[i]); for(int i=1;i<=m;i++){ cin>>opt; if(opt==1){ cin>>l>>k; add(l,k); } else { cin>>l>>r; cout<<query(r)-query(l-1)<<"\n"; } } }
线段树
点击查看
-
P3372 【模板】线段树 1
结构体版
#include<bits/stdc++.h> using namespace std; struct node{ int l,r; long long lazy,sum; }z[400028]; int a[100308]; void build(int l,int r,int p){ z[p].l=l; z[p].r=r; if(l==r){ z[p].sum=a[l]; return ; } int mid=l+r>>1; build(l,mid,p*2); build(mid+1,r,p*2+1); z[p].sum=z[p*2].sum+z[p*2+1].sum; } void lazzy(int p){ if(z[p].lazy){ z[p*2].sum+=z[p].lazy*(z[p*2].r-z[p*2].l+1); z[p*2+1].sum+=z[p].lazy*(z[p*2+1].r-z[p*2+1].l+1); z[p*2].lazy+=z[p].lazy; z[p*2+1].lazy+=z[p].lazy; z[p].lazy=0; } } void chan(int l,int r,int p,int k){ if(l<=z[p].l&&r>=z[p].r){ z[p].sum+=(long long)k*(z[p].r-z[p].l+1); z[p].lazy+=k; return ; } lazzy(p); int mid=z[p].l+z[p].r>>1; if(l<=mid){ chan(l,r,p*2,k); } if(r>mid){ chan(l,r,p*2+1,k); } z[p].sum=z[p*2].sum+z[p*2+1].sum; } long long find(int l,int r,int p){ long long ans=0; if(l<=z[p].l&&r>=z[p].r){ return z[p].sum; } lazzy(p); int mid=z[p].l+z[p].r>>1; if(l<=mid){ ans+=find(l,r,p*2); } if(r>mid){ ans+=find(l,r,p*2+1); } return ans; } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,n,1); for(int i=1;i<=m;i++){ int opt; scanf("%d",&opt); if(opt==1){ int x,y,k; scanf("%d%d%d",&x,&y,&k); chan(x,y,1,k); } else{ int x,y; scanf("%d%d",&x,&y); printf("%lld\n",find(x,y,1)); } } }传参版
#include<bits/stdc++.h> #define ll long long using namespace std; int n,m; const int N=2e5+20; ll a[N]; struct node{ ll sum,lazy; }z[5*N]; void pushup(int x){ z[x].sum=z[x<<1].sum+z[x<<1|1].sum;} void build(int l,int r,int x){ z[x].lazy=0; if(l==r){ z[x].sum=a[l]; return ; } int mid=l+r>>1; build(l,mid,x<<1),build(mid+1,r,x<<1|1); pushup(x); } int opt,x,y; ll k; void Lazy(int x,int l,int r){ int mid=l+r>>1; if(z[x].lazy){ z[x<<1].sum+=1ll*(mid-l+1)*z[x].lazy; z[x<<1|1].sum+=1ll*(r-mid)*z[x].lazy; z[x<<1].lazy+=z[x].lazy,z[x<<1|1].lazy+=z[x].lazy; z[x].lazy=0; } } void change(int l,int r,int L,int R,ll k,int x){ if(L<=l&&r<=R){ z[x].sum=z[x].sum+1ll*(r-l+1)*k; z[x].lazy+=k; return ; } Lazy(x,l,r); int mid=l+r>>1; if(L<=mid) change(l,mid,L,R,k,x<<1); if(R>mid) change(mid+1,r,L,R,k,x<<1|1); pushup(x); } ll Sum(int l,int r,int L,int R,int x){ if(L<=l&&r<=R){ return z[x].sum; } Lazy(x,l,r); int mid=l+r>>1; ll s=0; if(L<=mid) s+=Sum(l,mid,L,R,x<<1); if(R>mid) s+=Sum(mid+1,r,L,R,x<<1|1); return s; } signed main(){ ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; build(1,n,1); for(int i=1;i<=m;i++){ cin>>opt>>x>>y; if(opt==1){ cin>>k; change(1,n,x,y,k,1); } else{ cout<<Sum(1,n,x,y,1)<<"\n"; } } } -
线段树2
结构体版:
#include<bits/stdc++.h> using namespace std; int n,q,mod; int a[100004]; struct node{ int l,r,sum,lazy1,lazy2; }t[1000004]; void build(int l,int r,int k){ t[k].l=l; t[k].r=r; t[k].lazy1=1; t[k].lazy2=0; if(l==r){ t[k].sum=a[l]; return ; } int mid=l+r>>1; build(l,mid,k*2); build(mid+1,r,k*2+1); t[k].sum=t[k*2].sum+t[k*2+1].sum; } void lazzy(int k){ t[k*2].sum=(1ll*t[k*2].sum*t[k].lazy1+1ll*t[k].lazy2*(t[k*2].r-t[k*2].l+1)%mod)%mod; t[k*2+1].sum=(1ll*t[k*2+1].sum*t[k].lazy1+1ll*t[k].lazy2*(t[k*2+1].r-t[k*2+1].l+1)%mod)%mod; t[k*2].lazy1=1ll*t[k*2].lazy1*t[k].lazy1%mod; t[k*2+1].lazy1=1ll*t[k*2+1].lazy1*t[k].lazy1%mod; t[k*2].lazy2=(1ll*t[k].lazy1*t[k*2].lazy2+t[k].lazy2)%mod; t[k*2+1].lazy2=(1ll*t[k].lazy1*t[k*2+1].lazy2+t[k].lazy2)%mod; t[k].lazy1=1,t[k].lazy2=0; } void chan(int l,int r,int p,int k){ if(t[k].l>=l&&t[k].r<=r){ t[k].sum=1ll*t[k].sum*p%mod; t[k].lazy1=1ll*t[k].lazy1*p%mod; t[k].lazy2=1ll*t[k].lazy2*p%mod; return ; } lazzy(k); int mid=t[k].l+t[k].r>>1; if(l<=mid){ chan(l,r,p,k*2); } if(r>mid){ chan(l,r,p,k*2+1); } t[k].sum=t[k*2].sum+t[k*2+1].sum; } void Chan(int l,int r,int p,int k){ if(t[k].l>=l&&t[k].r<=r){ t[k].sum=t[k].sum+1ll*(t[k].r-t[k].l+1)*p; t[k].lazy2+=p; return ; } lazzy(k); int mid=t[k].l+t[k].r>>1; if(l<=mid){ Chan(l,r,p,k*2); } if(r>mid){ Chan(l,r,p,k*2+1); } t[k].sum=t[k*2].sum+t[k*2+1].sum; } int find(int l,int r,int k){ if(t[k].l>=l&&t[k].r<=r){ return t[k].sum; } lazzy(k); int summ=0,mid=t[k].l+t[k].r>>1; if(l<=mid){ summ+=find(l,r,k*2); summ%=mod; } if(r>mid){ summ+=find(l,r,k*2+1); summ%=mod; } return summ; } signed main(){ scanf("%d%d%d",&n,&q,&mod); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,n,1); while(q--){ int opt; scanf("%d",&opt); if(opt==1){ int x,y,k; scanf("%d%d%d",&x,&y,&k); chan(x,y,k,1); } if(opt==2){ int x,y,k; scanf("%d%d%d",&x,&y,&k); Chan(x,y,k,1); } if(opt==3){ int x,y; scanf("%d%d",&x,&y); printf("%d\n",find(x,y,1)); } } }传参版:
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=1e5+20; int n,q,mod; ll a[N]; struct node{ ll mul,add,sum; }z[5*N]; void pushup(int x){ z[x].sum=z[x<<1].sum+z[x<<1|1].sum; } void build(int l,int r,int x){ z[x].add=0,z[x].mul=1; if(l==r){ z[x].sum=a[l]; return ; } int mid=l+r>>1; build(l,mid,x<<1),build(mid+1,r,x<<1|1); pushup(x); } int opt,x,y,k; void Lazy(int x,int l,int r){ int mid=l+r>>1; z[x<<1].sum=(1ll*z[x<<1].sum*z[x].mul%mod+1ll*(mid-l+1)*z[x].add%mod)%mod; z[x<<1|1].sum=(1ll*z[x<<1|1].sum*z[x].mul%mod+1ll*(r-mid)*z[x].add%mod)%mod; z[x<<1].add=(z[x<<1].add*z[x].mul%mod+z[x].add)%mod; z[x<<1|1].add=(z[x<<1|1].add*z[x].mul%mod+z[x].add)%mod; z[x<<1].mul=(z[x<<1].mul*z[x].mul)%mod; z[x<<1|1].mul=(z[x<<1|1].mul*z[x].mul)%mod; z[x].add=0,z[x].mul=1; } void Mul(int l,int r,int L,int R,int k,int x){ if(l>=L&&r<=R){ z[x].mul=1ll*z[x].mul*k%mod; z[x].add=1ll*z[x].add*k%mod; z[x].sum=1ll*z[x].sum*k%mod; return ; } Lazy(x,l,r); int mid=l+r>>1; if(L<=mid) Mul(l,mid,L,R,k,x<<1); if(R>mid) Mul(mid+1,r,L,R,k,x<<1|1); pushup(x); } void Add(int l,int r,int L,int R,int k,int x){ if(l>=L&&r<=R){ z[x].add=(z[x].add+k)%mod; z[x].sum=(z[x].sum+(r-l+1)*k%mod)%mod; return ; } Lazy(x,l,r); int mid=l+r>>1; if(L<=mid) Add(l,mid,L,R,k,x<<1); if(R>mid) Add(mid+1,r,L,R,k,x<<1|1); pushup(x); } ll Sum(int l,int r,int L,int R,int x){ if(l>=L&&r<=R){ return z[x].sum; } Lazy(x,l,r); int mid=l+r>>1; ll s=0; if(L<=mid) s=(s+Sum(l,mid,L,R,x<<1))%mod; if(R>mid) s=(s+Sum(mid+1,r,L,R,x<<1|1))%mod; return s; } signed main(){ cin>>n>>q>>mod; for(int i=1;i<=n;i++) cin>>a[i]; build(1,n,1); while(q--){ cin>>opt>>x>>y; if(opt==1){ cin>>k; Mul(1,n,x,y,k,1); } if(opt==2){ cin>>k; Add(1,n,x,y,k,1); } if(opt==3){ cout<<Sum(1,n,x,y,1)<<"\n"; } } }
树链剖分
点击查看
-
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]<<" "; }

浙公网安备 33010602011771号