一般图带花树匹配:
#include <bits/stdc++.h> using namespace std; #define N 230 int nex[N],spo[N],w[N],q[N],vis[N],mark[N]; vector<int>path[N]; int n,r,u,to; int finds(int x){ return w[x]==x?x:w[x]=finds(w[x]); } void tog(int x,int y){ x=finds(x),y=finds(y); if(x!=y)w[x]=y; } int findlca(int x,int y){ static int t=0; t++; while(1){ if(x){ x=finds(x); if(vis[x]==t)return x; vis[x]=t; if(spo[x])x=nex[spo[x]]; else x=0; } swap(x,y); } } void goup(int a,int p){ while(a!=p){ int b=spo[a],c=nex[b]; if(finds(c)!=p)nex[c]=b; if(mark[b]==2)mark[q[r++]=b]=1; if(mark[c]==2)mark[q[r++]=c]=1; tog(a,b);tog(b,c); a=c; } } bool aug(int s){ for(int i=1;i<=n;i++)nex[i]=-1,w[i]=i,mark[i]=0,vis[i]=-1; q[0]=s;r=1;mark[s]=1; for(int l=0;!spo[s]&&l<r;l++){ int x=q[l]; for(int i=0;i<(int)path[x].size();i++){ int y=path[x][i]; if(spo[x]!=y&&finds(x)!=finds(y)&&mark[y]!=2){ if(mark[y]==1){ int p=findlca(x,y); if(finds(x)!=p)nex[x]=y; if(finds(y)!=p)nex[y]=x; goup(y,p);goup(x,p); }else if (!spo[y]){ nex[y]=x; for(int j=y;j;){ int k=nex[j],p=spo[k]; spo[j]=k;spo[k]=j; j=p; } return true; }else { nex[y]=x; mark[q[r++]=spo[y]]=1; mark[y]=2; } } } } return false; } int main() { cin>>n; while(scanf("%d%d",&u,&to)!=EOF){ path[u].push_back(to); path[to].push_back(u); } int ans=0; for(int i=1;i<=n;i++)ans+=(!spo[i]&&aug(i)); printf("%d\n",ans*2); for(int i=1;i<=n;i++){ if(spo[i])printf("%d %d\n",i,spo[i]); spo[spo[i]]=0; } }
分治FFT:
#include <bits/stdc++.h> using namespace std; #define N 1000005 #define go(i,a,b) for(int i=(a);i<=(b);i++) #define ms(a,b) memset(a,b,sizeof a) #define inf 0x3f3f3f3f #define mid (l+r)/2 #define pi acos(-1.0) struct Complex{ double x,y; Complex(double _x = 0.0, double _y = 0.0){ x = _x; y = _y; } Complex operator -(const Complex &b)const{ return Complex(x - b.x, y - b.y); } Complex operator +(const Complex &b)const{ return Complex(x + b.x, y + b.y); } Complex operator *(const Complex &b)const{ return Complex(x * b.x - y * b.y, x * b.y + y * b.x); } }; void change(Complex y[],int len){ int i,j,k; for(i = 1, j = len / 2; i < len - 1; i++){ if(i < j) swap(y[i],y[j]); k = len / 2; while(j >= k){ j -= k; k /= 2; } if(j < k) j += k; } } void fft(Complex y[],int len,int on){ change(y,len); for(int h = 2; h <= len; h <<= 1){ Complex wn(cos(-on*2*pi/h),sin(-on*2*pi/h)); for(int j = 0; j < len; j += h){ Complex w(1,0); for(int k = j; k < j + h / 2; k++){ Complex u = y[k]; Complex t = w * y[k + h / 2]; y[k] = u + t; y[k + h / 2] = u - t; w = w * wn; } } } if(on == -1){ for(int i = 0; i < len; i++) y[i].x /= len; } } Complex A[N],B[N]; int f[N],a[N],n; #define mod 313 int cdq(int l,int r){ if(l==r)return f[r]; cdq(l,mid); int len=1; while(len/2<r-l+1)len*=2; go(i,0,len-1)A[i]=B[i]=Complex(0,0); go(i,l,mid)A[i-l].x=f[i]; go(i,0,r-l)B[i].x=a[i]; fft(A,len,1);fft(B,len,1); go(i,0,len-1)A[i]=A[i]*B[i]; fft(A,len,-1); go(i,mid+1,r)(f[i]+=(int)(A[i-l].x+0.5))%=mod; cdq(mid+1,r); return f[r]; } int main() { while(scanf("%d",&n)!=EOF&&n){ ms(f,0);f[0]=1; go(i,1,n)scanf("%d",&a[i]),a[i]%=mod; printf("%d\n",cdq(0,n)); } }
长链剖分:
#include <bits/stdc++.h> using namespace std; #define N 1000005 #define go(i,a,b) for(int i=(a);i<=(b);i++) #define pb push_back vector<int>path[N]; int *f[N],son[N],len[N],ans[N],tmp[N],*id=tmp, n; void dfs(int u,int fa){ for(int to:path[u]){ if(to==fa)continue; dfs(to,u); if(len[to]>len[son[u]])son[u]=to; } len[u]=len[son[u]]+1; } void dpdfs(int u,int fa){ f[u][0]=1; if(son[u])f[son[u]]=f[u]+1,dpdfs(son[u],u),ans[u]=ans[son[u]]+1; for(int to:path[u]){ if(to==fa||to==son[u])continue; f[to]=id;id+=len[to]; dpdfs(to,u); go(i,1,len[to]){ f[u][i]+=f[to][i-1]; if(f[u][i]>f[u][ans[u]]||(f[u][i]==f[u][ans[u]]&&i<ans[u]))ans[u]=i; } } if(f[u][ans[u]]==1)ans[u]=0; } int u,to; int main() { cin>>n; go(i,2,n)scanf("%d%d",&u,&to),path[u].pb(to),path[to].pb(u); dfs(1,0);f[1]=id;id+=len[1]; dpdfs(1,0); go(i,1,n)printf("%d\n",ans[i]); return 0; }
斯坦纳树:
#include <bits/stdc++.h> using namespace std; #define go(i,a,b) for(int i=(a);i<=(b);i++) #define dep(i,a,b) for(int i=(a);i>=(b);i--) #define inf 0x3f3f3f3f #define N 1010 struct no{ int to,n,w; };no eg[N*10]; int h[N],is[N],tot=1,n,m,k; void add(int u,int to,int w){ eg[tot]={to,h[u],w};h[u]=tot++; eg[tot]={u,h[to],w};h[to]=tot++; } int dp[N][1<<11],dk[1<<11]; queue<int>q; void spfa(int s){ go(i,1,n)if(dp[i][s]<inf)q.push(i),is[i]=1; while(!q.empty()){ int x=q.front();q.pop(); is[x]=0; for(int i=h[x];i;i=eg[i].n){ int to=eg[i].to,w=eg[i].w; if(dp[to][s]>dp[x][s]+w){ dp[to][s]=dp[x][s]+w; if(!is[to])q.push(to),is[to]=1; } } } } int a,b[N],hx[N],u,w,to; int main() { cin>>n>>m>>k; memset(dp,inf,sizeof(dp)); memset(dk,inf,sizeof(dk)); go(i,1,m)scanf("%d%d%d",&u,&to,&w),add(u,to,w); go(i,1,k)scanf("%d%d",&b[i],&a),dp[a][1<<(i-1)]=0,hx[b[i]]|=1<<(i-1); sort(b+1,b+k+1); int siz=unique(b+1,b+k+1)-b-1; int S=(1<<k)-1,SS=(1<<siz)-1; go(s,0,S){ go(i,1,n) for(int t=s;t;t=(t-1)&s) dp[i][s]=min(dp[i][s],dp[i][t]+dp[i][s^t]); spfa(s); } go(i,0,SS){ int tmp=0; go(j,0,siz-1)if(i&(1<<j))tmp|=hx[b[j+1]]; go(j,1,n)dk[i]=min(dk[i],dp[j][tmp]); } go(s,0,SS) for(int t=s;t;t=(t-1)&s) dk[s]=min(dk[s],dk[t]+dk[s^t]); cout<<dk[SS]<<endl; return 0; }
#include <bits/stdc++.h> using namespace std; const int mod=1000000007; const int N=60; const int inf=0x3f3f3f3f; typedef pair<int,int> pii; int h[N],done[N],tot=1,n,m,k; pii operator*(const pii &A, const pii &B) { return {A.first+B.first, 1LL*A.second*B.second%mod}; } inline void upd(pii &A, const pii &B) { if(A.first > B.first) A = B; else if(A.first == B.first) A.second = (A.second+B.second)%mod; } pii dp[1<<12][N],dk[1<<12][N]; priority_queue<pii,vector<pii>,greater<pii> >Q; vector<int>G[N]; void dij(pii *g, pii *f) { for(int i = 0; i < n; i++) { if(g[i].first != inf) Q.push({g[i].first, i}); done[i] = 0; } while(!Q.empty()) { pii t = Q.top(); Q.pop(); int u = t.second; if(done[u]) continue; done[u] = 1; for(int v:G[u]) if(g[v].first >= g[u].first+1) { bool flag = g[v].first>g[u].first+1; upd(g[v], g[u]*pii(1, 1)); upd(f[v], g[u]*pii(1, 1)); if(flag) Q.push({g[v].first, v}); } } } int main() { while(1){ if(scanf("%d%d%d", &n, &m, &k) == -1) exit(0); int all=(1<<k)-1; for(int u = 0; u < n; u++) { G[u].clear(); for(int S = 0; S <= all; S++) dp[S][u] = dk[S][u] = {inf, 0}; if(u < k) dk[1<<u][u] = dp[1<<u][u] = {0, 1}; } while(m--) { int u, v; scanf("%d%d", &u, &v); G[u-1].push_back(v-1), G[v-1].push_back(u-1); } for(int S = 0; S <= all; S++) { for(int u = 0; u < n; u++) for(int S0 = (S-1)&S; S0; S0 = (S0-1)&S) if((S0&-S0) == (S&-S)) upd(dp[S][u], dk[S0][u]*dp[S^S0][u]); dij(dp[S], dk[S]); } printf("%d\n",dp[all][0].second); } return 0; }
按秩合并并查集:
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include <bits/stdc++.h> using namespace std; const int N=200000+100; int ans[N*2]; struct UnF { int size[N],fa[N],mstack[N*4],top; void Init(int n) { for(int i=1; i<=n; i++) size[i]=1; } int FindFather(int x) { if(fa[x]==0) return x; return FindFather(fa[x]); } void Link(int x,int y) { mstack[++top]=0; int fa_x=FindFather(x),fa_y=FindFather(y); if(size[fa_x]>size[fa_y]) swap(x,y),swap(fa_x,fa_y); if(fa_x==fa_y) return; mstack[top]=fa_x; fa[fa_x]=fa_y,size[fa_y]+=size[fa_x]; } int Query(int x,int y) { if(FindFather(x)==FindFather(y)) return true; return false; } void Undo() { if(mstack[top]==0) { top--; return; } size[fa[mstack[top]]]-=size[mstack[top]]; fa[mstack[top]]=0; top--; } } unf; int n,m; #define pii pair<int,int> struct SegmentTree { #define mid ((now_l+now_r)>>1) #define lson (now<<1) #define rson (now<<1|1) vector <pii> w[N<<2]; void Insert(int l,int r,int x,int y,int now,int now_l,int now_r) { if(now_l>=l and now_r<=r) { w[now].push_back(pii(x,y)); return; } if(l<=mid) Insert(l,r,x,y,lson,now_l,mid); if(r>mid) Insert(l,r,x,y,rson,mid+1,now_r); } void dfs(int now,int now_l,int now_r) { if(now_l>now_r) return; for(pii x:w[now]) unf.Link(x.first,x.second); if(now_l==now_r) ans[now_l]=unf.Query(1,n); else { dfs(lson,now_l,mid); dfs(rson,mid+1,now_r); } for(int i=0; i<int(w[now].size()); i++) unf.Undo(); } #undef mid #undef lson #undef rson } sgt; struct no { int u, to,l,r; }; no d[N]; int lsx[N*2]; #define go(i,a,b) for(int i=(a);i<=(b);i++) int main() { cin>>n>>m; unf.Init(n+1); go(i,1,m) { scanf("%d%d%d%d",&d[i].u,&d[i].to,&d[i].l,&d[i].r); lsx[i]=d[i].l,lsx[m+i]=d[i].r+1; } sort(lsx+1,lsx+m*2+1); int q=unique(lsx+1,lsx+m*2+1)-(lsx+1); go(i,1,m) { int l=lower_bound(lsx+1,lsx+q+1,d[i].l)-lsx; int r=lower_bound(lsx+1,lsx+q+1,d[i].r+1)-lsx-1; sgt.Insert(l,r,d[i].u,d[i].to,1,1,q); } sgt.dfs(1,1,q); int as=0; go(i,1,q)if(ans[i]) as+=lsx[i+1]-lsx[i]; cout<<as<<endl; }
LCT:
#include <bits/stdc++.h> using namespace std; #define N 200005 #define ls c[x][0] #define rs c[x][1] struct LCT { int fa[N],ch[N][2],rev[N],sz[N],q[N]; void init() { memset(ch,0,sizeof ch); memset(fa,0,sizeof fa); memset(sz,0,sizeof sz); memset(rev,0,sizeof rev); } inline bool isroot(int x) { return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } inline void pushup(int x) { sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; } inline void pushdown(int x) { if(rev[x]) { rev[x]=0; swap(ch[x][0],ch[x][1]); rev[ch[x][0]]^=1,rev[ch[x][1]]^=1; } } inline void Rotate(int x) { int y=fa[x],z=fa[y],l,r; if(ch[y][0]==x) l=0,r=l^1; else l=1,r=l^1; if(!isroot(y)) { if(ch[z][0]==y) ch[z][0]=x; else ch[z][1]=x; } fa[x]=z; fa[y]=x; fa[ch[x][r]]=y; ch[y][l]=ch[x][r]; ch[x][r]=y; pushup(y); pushup(x); } inline void splay(int x) { int top=1; q[top]=x; for(int i=x; !isroot(i); i=fa[i]) q[++top]=fa[i]; for(int i=top; i; i--) pushdown(q[i]); while(!isroot(x)) { int y=fa[x],z=fa[y]; if(!isroot(y)) { if((ch[y][0]==x)^(ch[z][0]==y)) Rotate(x); else Rotate(y); } Rotate(x); } } inline void access(int x) { for(int y=0; x; y=x,x=fa[x]) splay(x),ch[x][1]=y,pushup(x); } inline void makeroot(int x) { access(x),splay(x),rev[x]^=1; } inline int findroot(int x) { access(x),splay(x); while(ch[x][0]) x=ch[x][0]; return x; } inline void split(int x,int y) { makeroot(x),access(y),splay(y); } inline void cut(int x,int y) { split(x,y); if(ch[y][0]==x) ch[y][0]=0,fa[x]=0; } inline void link(int x,int y) { makeroot(x),fa[x]=y,splay(x); } } lct; int fa[N][22],h[N]; int n,m,l,rr,op,tot; inline int getfa(int u,int k) { for(int i=16; i>=0; i--) if((1<<i)<=k) u=fa[u][i],k-=(1<<i); return !u?n+1:u; } int v[N]; int main() { int T; cin>>T; while(T--) { scanf("%d",&n); lct.init(); for(int i=2; i<=n; i++) scanf("%d",&fa[i][0]); for(int j=1; j<=17; j++) for(int i=1; i<=n; i++) fa[i][j]=fa[fa[i][j-1]][j-1]; for(int i=1; i<=n; i++) scanf("%d",&v[i]); for(int i=1; i<=n; i++) lct.link(i,getfa(i,v[i])); scanf("%d",&m); for(int i=1; i<=m; i++) { scanf("%d",&op); if(op==1) { scanf("%d",&rr); lct.split(n+1,rr); printf("%d\n",lct.sz[rr]-1); } else { scanf("%d %d",&l,&rr); lct.cut(l,getfa(l,v[l])); v[l]=rr; lct.link(l,getfa(l,v[l])); } } //for(int i=1;i<=n;i++)cut(i,getfa(i,v[i])); } return 0; }
欧拉回路路径树
#include <bits/stdc++.h> using namespace std; #define N 300005 #define go(i,a,b) for(int i=(a);i<=(b);i++) #define inf 0x3f3f3f3f #define mod 998244353 #define ll long long int ny(int x){return x==1?1:1ll*ny(mod%x)*(mod-mod/x)%mod; } ll a[410][410],jx[N]; int in[N],out[N],n; ll det(int n)//求前n行n列的行列式的值 { go(i,1,n)go(j,1,n)a[i][j]=(a[i][j]%mod+mod)%mod; ll ret=1; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) while(a[j][i]) { ll t=a[i][i]/a[j][i]; for(int k=i;k<=n;++k) a[i][k]=((a[i][k]-a[j][k]*t)%mod+mod)%mod; for(int k=i;k<=n;++k) swap(a[i][k],a[j][k]); ret=-ret; } if(!a[i][i]) return 0; ret=ret*a[i][i]%mod; } ret=(ret%mod+mod)%mod; return ret; } int x,cas=1; int main() { jx[0]=1;go(i,1,N-1)jx[i]=jx[i-1]*i%mod; while(scanf("%d",&n)!=EOF){ ll ans=1; go(i,0,n)go(j,0,n)a[i][j]=out[i]=in[i]=0; go(i,1,n){ go(j,1,n){ scanf("%d",&x); a[i][j]-=x; a[j][j]+=x; in[i]+=x; out[j]+=x; if(x)(ans*=ny(jx[x]))%=mod; } (ans*=(jx[in[i]-1]+mod)%mod)%=mod; } int fl=1; go(i,1,n)if(in[i]!=out[i])fl=0; (ans*=det(n-1))%=mod; // cout<<ans<<endl; printf("Case #%d: %lld\n",cas++,ans*in[1]*fl%mod); } return 0; }
李超树
#include <bits/stdc++.h> #include <bits/stdc++.h> using namespace std; #define N 200005 #define ll long long #define mod 1000000007 #define go(i,a,b) for(int i=(a);i<=(b);i++) #define dep(i,a,b) for(int i=(a);i>=(b);i--) #define pb push_back #define inf 0x3f3f3f3f #define ld long double #define pii pair<int,int> #define vi vector<int> #define add(a,b) (a+=(b)%mod)%=mod #define lowb(x,c,len) lower_bound(c+1,c+len+1,x)-c #define uppb(x,c,len) upper_bound(c+1,c+len+1,x)-c #define ls i*2+1 #define rs i*2+2 #define mid (l+r)/2 #define lson l,mid,ls #define rson mid+1,r,rs #define root 1,n,0 #define ms(a,b) memset(a,b,sizeof a) #define muti int T;cin>>T;while(T--) int t[N*4]; ld k[N],b[N]; ld lsx[N],x[N],y[N]; ld f(int id,int x){return k[id]*lsx[x]+b[id]; } void updata(int x,int l,int r,int i){ if(f(x,l)>=f(t[i],l)&&f(x,r)>=f(t[i],r))return ; if(f(x,l)<f(t[i],l)&&f(x,r)<=f(t[i],r)){t[i]=x;return ;} if(f(x,l)<f(t[i],l)){ if(f(x,mid)<f(t[i],mid)){ updata(t[i],rson); t[i]=x; } else updata(x,lson); } else { if(f(x,mid)<f(t[i],mid)){ updata(t[i],lson); t[i]=x; } else updata(x,rson); } } ld query(int x,int l,int r,int i){ ld res=f(t[i],x); if(l==r)return res; if(x<=mid)res=min(res,query(x,lson)); else res=min(res,query(x,rson)); return res; } ld w,c,ans,sum;int n; ld as(int i){ return lsx[i]+(w-sum-c)/k[i]; } int main() { ios::sync_with_stdio(false); cin>>w>>n>>c; k[0]=1,b[0]=0; go(i,1,n)cin>>lsx[i]>>x[i]>>y[i]; go(i,1,n){ sum=query(i,root); k[i]=y[i]/x[i];b[i]=sum-k[i]*lsx[i]+c; updata(i,root); if(sum+c<w)ans=max(ans,as(i)); } cout<<fixed<<setprecision(9)<<ans<<endl; }