过滤一些较简单的如线段树、树状数组等,甚至树链剖分都被过滤了。
左偏树:https://www.luogu.org/problemnew/show/P3377
#include<bits/stdc++.h> using namespace std; const int N=1e6+7; int n,Q,fa[N],lc[N],rc[N],w[N],d[N]; int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} int merge(int x,int y) { if(!x||!y)return x+y; if(w[x]>w[y]||w[x]==w[y]&&x>y)swap(x,y); rc[x]=merge(rc[x],y); if(d[lc[x]]<d[rc[x]])swap(lc[x],rc[x]); d[x]=d[rc[x]]+1; return x; } int main() { scanf("%d%d",&n,&Q); for(int i=1;i<=n;i++)scanf("%d",&w[i]),fa[i]=i; d[0]=-1; while(Q--) { int op,x,y;scanf("%d%d",&op,&x); if(op==1) { scanf("%d",&y); if(w[x]==-1||w[y]==-1)continue; int u=find(x),v=find(y); if(u!=v)fa[u]=fa[v]=merge(u,v); } else{ if(w[x]==-1){puts("-1");continue;} y=find(x); printf("%d ",w[y]); w[y]=-1,fa[y]=merge(lc[y],rc[y]),fa[fa[y]]=fa[y]; } } }
主席树:https://www.luogu.org/problemnew/show/P3834
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=2e5+7; int n,Q,cnt,m,a[N],b[N],root[N],sum[N*30],lc[N*30],rc[N*30]; int build(int l,int r) { int rt=++cnt,mid=(l+r)/2; sum[rt]=0; if(l<r)lc[rt]=build(l,mid),rc[rt]=build(mid+1,r); return rt; } int update(int prt,int l,int r,int k) { int rt=++cnt,mid=(l+r)/2; lc[rt]=lc[prt];rc[rt]=rc[prt];sum[rt]=sum[prt]+1; if(l==r)return rt; if(k<=mid)lc[rt]=update(lc[prt],l,mid,k); else rc[rt]=update(rc[prt],mid+1,r,k); return rt; } int query(int L,int R,int l,int r,int k) { if(l>=r)return l; int x=sum[lc[R]]-sum[lc[L]],mid=(l+r)/2; if(x>=k)return query(lc[L],lc[R],l,mid,k); return query(rc[L],rc[R],mid+1,r,k-x); } int main() { scanf("%d%d",&n,&Q); for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i]; sort(b+1,b+n+1); m=unique(b+1,b+n+1)-b-1; for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+m+1,a[i])-b; root[0]=build(1,m); for(int i=1;i<=n;i++)root[i]=update(root[i-1],1,m,a[i]); while(Q--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); printf("%d ",b[query(root[x-1],root[y],1,m,z)]); } }
可持久化并查集:https://www.luogu.org/problemnew/show/P3402
#include<bits/stdc++.h> using namespace std; const int N=2e5+7; int n,m,tot,root[N],fa[N*30],dep[N*30],lc[N*30],rc[N*30]; void build(int&rt,int l,int r) { rt=++tot; if(l==r){fa[rt]=l;return;} int mid=(l+r)/2; build(lc[rt],l,mid); build(rc[rt],mid+1,r); } void update(int&rt,int prt,int l,int r,int pos,int f) { rt=++tot; if(l==r){fa[rt]=f,dep[rt]=dep[prt];return;} lc[rt]=lc[prt],rc[rt]=rc[prt]; int mid=(l+r)/2; if(pos<=mid)update(lc[rt],lc[prt],l,mid,pos,f); else update(rc[rt],rc[prt],mid+1,r,pos,f); } int query(int rt,int l,int r,int pos) { if(l==r)return rt; int mid=(l+r)/2; if(pos<=mid)return query(lc[rt],l,mid,pos); return query(rc[rt],mid+1,r,pos); } int find_fa(int rt,int x) { int y=query(rt,1,n,x); if(x==fa[y])return y; return find_fa(rt,fa[y]); } void add(int rt,int l,int r,int pos) { if(l==r){dep[rt]++;return;} int mid=(l+r)/2; if(pos<=mid)add(lc[rt],l,mid,pos); else add(rc[rt],mid+1,r,pos); } int main() { scanf("%d%d",&n,&m); build(root[0],1,n); for(int i=1,op,x,y;i<=m;i++) { scanf("%d%d",&op,&x); if(op==1) { scanf("%d",&y); root[i]=root[i-1]; x=find_fa(root[i],x); y=find_fa(root[i],y); if(fa[x]==fa[y])continue; if(dep[x]>dep[y])swap(x,y); update(root[i],root[i-1],1,n,fa[x],fa[y]); if(dep[x]==dep[y])add(root[i],1,n,fa[y]); } else if(op==2)root[i]=root[x]; else{ scanf("%d",&y); root[i]=root[i-1]; x=find_fa(root[i],x); y=find_fa(root[i],y); if(fa[x]==fa[y])puts("1");else puts("0"); } } }
线段树合并:https://www.lydsy.com/JudgeOnline/problem.php?id=2212
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e6+77; int n,lc[N],rc[N],cnt[N],tot=0; ll ans; int merge(int rt1,int rt2,int l,int r,ll&s1,ll&s2) { if(!rt1||!rt2)return rt1+rt2; if(l==r){cnt[rt1]+=cnt[rt2];return rt1;} int mid=(l+r)/2; s1+=1ll*cnt[rc[rt1]]*cnt[lc[rt2]]; s2+=1ll*cnt[rc[rt2]]*cnt[lc[rt1]]; lc[rt1]=merge(lc[rt1],lc[rt2],l,mid,s1,s2); rc[rt1]=merge(rc[rt1],rc[rt2],mid+1,r,s1,s2); cnt[rt1]=cnt[lc[rt1]]+cnt[rc[rt1]]; return rt1; } int build(int l,int r,int k) { int x=++tot; if(l==r){cnt[x]=1;return x;} int mid=(l+r)/2; if(k<=mid)lc[x]=build(l,mid,k); else rc[x]=build(mid+1,r,k); cnt[x]=cnt[lc[x]]+cnt[rc[x]]; return x; } int dfs() { int x; scanf("%d",&x); if(x)return build(1,n,x); ll s1=0,s2=0; int u=dfs(),v=dfs(),rt=merge(u,v,1,n,s1,s2); ans+=min(s1,s2); return rt; } int main() { scanf("%d",&n); dfs(); printf("%lld",ans); }
树上启发式合并:https://www.luogu.org/problemnew/show/P3302
#include<bits/stdc++.h> using namespace std; const int N=80100; int n,m,p,a[N],b[N],rt[N],sz[N],fa[N],dep[N],f[N][20]; vector<int>G[N]; namespace tree{ struct seg{int lc,rc,s;}tr[N*400]; int sz; void update(int k,int l,int r,int&rt,int prt) { tr[rt=++sz]=tr[prt],tr[rt].s++; if(l==r)return; int mid=l+r>>1; if(k<=mid)update(k,l,mid,tr[rt].lc,tr[prt].lc); else update(k,mid+1,r,tr[rt].rc,tr[prt].rc); } int query(int u,int v,int pu,int pv,int k,int l,int r) { if(l==r)return l; int mid=l+r>>1,sum=tr[tr[u].lc].s+tr[tr[v].lc].s-tr[tr[pu].lc].s-tr[tr[pv].lc].s; if(k<=sum)return query(tr[u].lc,tr[v].lc,tr[pu].lc,tr[pv].lc,k,l,mid); return query(tr[u].rc,tr[v].rc,tr[pu].rc,tr[pv].rc,k-sum,mid+1,r); } } int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} void dfs(int u,int Fa,int anc) { f[u][0]=Fa; for(int i=1;i<=19;i++)f[u][i]=f[f[u][i-1]][i-1]; sz[anc]++,dep[u]=dep[Fa]+1,fa[u]=Fa; int x=lower_bound(b+1,b+p+1,a[u])-b; tree::update(x,1,p,rt[u],rt[Fa]); for(int i=0;i<G[u].size();i++)if(G[u][i]!=Fa)dfs(G[u][i],u,anc); } int lca(int x,int y) { if(dep[x]<dep[y])swap(x,y); int t=dep[x]-dep[y]; for(int i=0;(1<<i)<=t;i++)if(t&(1<<i))x=f[x][i]; if(x==y)return x; for(int i=19;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i]; return f[x][0]; } int main() { int Q;scanf("%*d%d%d%d",&n,&m,&Q); for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i],fa[i]=i; for(int i=1,x,y;i<=m ;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x); sort(b+1,b+n+1); p=unique(b+1,b+n+1)-b-1; for(int i=1;i<=n;i++)if(!dep[i])dfs(i,0,i),fa[i]=i; char op; int x,y,z,ans=0; while(Q--) { scanf(" %c%d%d",&op,&x,&y),x^=ans,y^=ans; if(op=='Q') { scanf("%d",&z),z^=ans; int Fa=lca(x,y); printf("%d ",ans=b[tree::query(rt[x],rt[y],rt[Fa],rt[f[Fa][0]],z,1,p)]); } else{ G[x].push_back(y),G[y].push_back(x); int fx=find(x),fy=find(y); if(sz[fx]<sz[fy])swap(x,y),swap(fx,fy); dfs(y,x,fx); } } }
可持久化Trie:https://www.luogu.org/problemnew/show/P4098
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>pii; const int N=50005; int n,cnt,ans,a[N],rt[N],ch[N*32][2],sz[N*32],L[N],R[N]; pii b[N]; void build(int x,int id) { int u,v=rt[id-1];u=rt[id]=++cnt; sz[u]=sz[v]+1; for(int i=29;~i;i--) { int c=x>>i&1; ch[u][c^1]=ch[v][c^1],ch[u][c]=++cnt; u=ch[u][c],v=ch[v][c],sz[u]=sz[v]+1; } } int query(int x,int l,int r) { if(l>r)return 0; l=rt[l-1],r=rt[r]; int ret=0; for(int i=29;~i;i--) { int c=x>>i&1; if(sz[ch[r][c^1]]-sz[ch[l][c^1]])ret+=1<<i,l=ch[l][c^1],r=ch[r][c^1]; else l=ch[l][c],r=ch[r][c]; } return ret; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]),build(a[i],i),b[i]=pii(a[i],i),L[i]=i-1,R[i]=i+1; sort(b+1,b+n+1); for(int i=1;i<=n;i++) { int x=b[i].second,l=L[x],r=R[x];L[r]=l,R[l]=r; if(l)ans=max(ans,query(a[x],L[l]+1,r-1)); if(r)ans=max(ans,query(a[x],l+1,R[r]-1)); } printf("%d",ans); }
动态开点线段树:https://www.lydsy.com/JudgeOnline/problem.php?id=3939
#include<bits/stdc++.h> #define lson l,mid,lc[rt] #define rson mid+1,r,rc[rt] using namespace std; const int N=760,M=N*N*15,mod=1e9+7; int n,m,k,cnt,a[N][N],f[N][N],s[N][N],sum[M],root[N*N],lc[M],rc[M]; void insert(int k,int c,int l,int r,int &rt) { if(!rt)rt=++cnt; if(l==r){sum[rt]=(sum[rt]+c)%mod;return;} int mid=(l+r)/2; if(k<=mid)insert(k,c,lson); else insert(k,c,rson); sum[rt]=(sum[lc[rt]]+sum[rc[rt]])%mod; } int query(int L,int R,int l,int r,int rt) { if(!rt)return 0; if(L<=l&&r<=R)return sum[rt]; int mid=(l+r)/2,ret=0; if(L<=mid)ret+=query(L,R,lson); if(R>mid)ret=(ret+query(L,R,rson))%mod; return ret; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); f[1][1]=1; for(int i=1;i<=m;i++)s[1][i]=1; for(int i=2;i<=n;i++) for(int j=1;j<=m;j++) { f[i][j]=s[i-1][j-1]; if(j>1)f[i][j]=(f[i][j]-query(1,j-1,1,m,root[a[i][j]])+mod)%mod; s[i][j]=(1ll*s[i][j-1]+s[i-1][j]-s[i-1][j-1]+f[i][j]+mod)%mod; insert(j,f[i-1][j],1,m,root[a[i-1][j]]); } printf("%d",f[n][m]); }
treap:https://www.luogu.org/problemnew/show/P3369
#include<bits/stdc++.h> using namespace std; const int N=1e5+7; int n,cnt,root,ans,lc[N],rc[N],sz[N],w[N],rnd[N],v[N]; void update(int rt){sz[rt]=sz[lc[rt]]+sz[rc[rt]]+w[rt];} void rturn(int&rt) { int t=lc[rt]; lc[rt]=rc[t];rc[t]=rt; sz[t]=sz[rt];update(rt);rt=t; } void lturn(int&rt) { int t=rc[rt]; rc[rt]=lc[t];lc[t]=rt; sz[t]=sz[rt];update(rt);rt=t; } void insert(int&rt,int val) { if(!rt) { rt=++cnt; sz[rt]=w[rt]=1; v[rt]=val;rnd[rt]=rand(); return; } sz[rt]++; if(v[rt]==val)w[rt]++; else if(v[rt]>val){insert(lc[rt],val);if(rnd[lc[rt]]<rnd[rt])rturn(rt);} else{insert(rc[rt],val);if(rnd[rc[rt]]<rnd[rt])lturn(rt);} } void del(int&rt,int val) { if(!rt)return; if(v[rt]==val) { if(w[rt]>1){w[rt]--;sz[rt]--;return;} if(lc[rt]*rc[rt]==0)rt=lc[rt]+rc[rt]; else if(rnd[lc[rt]]<rnd[rc[rt]])rturn(rt),del(rt,val); else lturn(rt),del(rt,val); return; } sz[rt]--; if(v[rt]>val)del(lc[rt],val); else del(rc[rt],val); } int query_rank(int rt,int val) { if(!rt)return 0; if(v[rt]==val)return sz[lc[rt]]+1; if(v[rt]>val)return query_rank(lc[rt],val); return sz[lc[rt]]+w[rt]+query_rank(rc[rt],val); } int query_num(int rt,int rnk) { if(!rt)return 0; if(rnk<=sz[lc[rt]])return query_num(lc[rt],rnk); if(rnk>sz[lc[rt]]+w[rt])return query_num(rc[rt],rnk-sz[lc[rt]]-w[rt]); return v[rt]; } void query_pre(int rt,int val) { if(!rt)return; if(v[rt]<val)ans=rt,query_pre(rc[rt],val); else query_pre(lc[rt],val); } void query_sub(int rt,int val) { if(!rt)return; if(v[rt]>val)ans=rt,query_sub(lc[rt],val); else query_sub(rc[rt],val); } int main() { srand(time(0)); scanf("%d",&n); for(int i=1,op,x;i<=n;i++) { scanf("%d%d",&op,&x); if(op==1)insert(root,x); if(op==2)del(root,x); if(op==3)printf("%d ",query_rank(root,x)); if(op==4)printf("%d ",query_num(root,x)); if(op==5)ans=0,query_pre(root,x),printf("%d ",v[ans]); if(op==6)ans=0,query_sub(root,x),printf("%d ",v[ans]); } }
splay:https://www.luogu.org/problemnew/show/P3391
#include<bits/stdc++.h> using namespace std; const int N=1e5+7; int n,m,root,sz[N],fa[N],ch[N][2]; bool rev[N]; void pushup(int rt){sz[rt]=sz[ch[rt][0]]+sz[ch[rt][1]]+1;} void pushdown(int rt) { if(rev[rt]) { swap(ch[rt][0],ch[rt][1]); rev[rt]=0; rev[ch[rt][0]]^=1,rev[ch[rt][1]]^=1; } } void rotate(int&rt,int x) { int y=fa[x],z=fa[y]; bool dy=ch[y][1]==x,dz=ch[z][1]==y; pushdown(y); if(y==rt)rt=x;else ch[z][dz]=x; fa[x]=z; ch[y][dy]=ch[x][dy^1],fa[ch[x][dy^1]]=y; ch[x][dy^1]=y,fa[y]=x; pushup(y); } void splay(int&rt,int x) { pushdown(x); while(x!=rt) { int y=fa[x],z=fa[y]; if(y!=rt) { if((ch[y][1]==x)^(ch[z][1]==y))rotate(rt,x); else rotate(rt,y); } rotate(rt,x); } pushup(x); } int find(int rt,int x) { if(!rt)return 0; pushdown(rt); if(x<=sz[ch[rt][0]])return find(ch[rt][0],x); if(x==sz[ch[rt][0]]+1)return rt; return find(ch[rt][1],x-sz[ch[rt][0]]-1); } void print(int rt) { if(!rt)return; pushdown(rt); print(ch[rt][0]); if(rt>1&&rt<n+2)printf("%d ",rt-1); print(ch[rt][1]); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n+2;++i)sz[i]=n+3-i,fa[i]=i-1,ch[i][1]=i+1; ch[n+2][1]=0,root=1; while(m--) { int l,r; scanf("%d%d",&l,&r); splay(root,find(root,l)); splay(ch[root][1],find(root,r+2)); rev[ch[ch[root][1]][0]]^=1; } print(root); }
替罪羊树:https://www.lydsy.com/JudgeOnline/problem.php?id=3065
#include<bits/stdc++.h> #define pb push_back using namespace std; const int N=71000,M=1e7+7; const double alpha=0.75; int n,m,sz,ans,root,tmp,v[N],dfn[N],rt[N],lc[N],rc[N]; struct seg{int l,r,sum;}a[M]; vector<int>rec,t,p; int newnode() { if(!rec.size())return++sz; int k=rec.back();rec.pop_back(); return k; } void reclaim(int&x) { if(!x)return; rec.pb(x); reclaim(a[x].l);reclaim(a[x].r); a[x].sum=0;x=0; } void insert(int &k,int l,int r,int p,int v) { if(!k)k=newnode(); if(l==r){a[k].sum+=v;return;} int mid=(l+r)/2; if(p<=mid)insert(a[k].l,l,mid,p,v); else insert(a[k].r,mid+1,r,p,v); a[k].sum=a[a[k].l].sum+a[a[k].r].sum; if(!a[k].sum)reclaim(k); } void build(int &k,int l,int r) { if(l>r)return; if(l==r) { k=dfn[l];insert(rt[k],0,70000,v[k],1);return; } int mid=(l+r)/2;k=dfn[mid]; build(lc[k],l,mid-1);build(rc[k],mid+1,r); for(int i=l;i<=r;i++)insert(rt[k],0,70000,v[dfn[i]],1); } void del(int &x) { if(!x)return;reclaim(rt[x]); del(lc[x]);p.pb(x);del(rc[x]); x=0; } void rebuild(int&x) { del(x); int s1=p.size(); for(int i=1;i<=s1;i++)dfn[i]=p[i-1]; build(x,1,s1); p.clear(); } int update(int k,int x,int val) { insert(rt[k],0,70000,val,1); int t,L=a[rt[lc[k]]].sum; if(L+1==x)t=v[k],v[k]=val; else if(L>=x)t=update(lc[k],x,val); else t=update(rc[k],x-L-1,val); insert(rt[k],0,70000,t,-1); return t; } void query(int k,int l,int r) { int L=a[rt[lc[k]]].sum,R=a[rt[k]].sum; if(l==1&&r==R){t.pb(rt[k]);return;} if(l<=L+1&&L+1<=r)p.pb(v[k]); if(r<=L)query(lc[k],l,r); else if(l>L+1)query(rc[k],l-L-1,r-L-1); else{ if(l<=L)query(lc[k],l,L); if(R>L+1)query(rc[k],1,r-L-1); } } int solve(int L,int R,int k) { query(root,L,R); k--; int l=0,r=70000,s1=t.size(),s2=p.size(); while(l<r) { int mid=(l+r)/2,sum=0; for(int i=0;i<s1;i++)sum+=a[a[t[i]].l].sum; for(int i=0;i<s2;i++)if(p[i]>=l&&p[i]<=mid)sum++; if(k<sum) { for(int i=0;i<s1;i++)t[i]=a[t[i]].l; r=mid; } else{ for(int i=0;i<s1;i++)t[i]=a[t[i]].r; l=mid+1;k-=sum; } } t.clear();p.clear(); return l; } void insert(int&k,int x,int val) { if(!k) { k=++n; insert(rt[k],0,70000,val,1); v[k]=val; return; } insert(rt[k],0,70000,val,1); int L=a[rt[lc[k]]].sum; if(L>=x)insert(lc[k],x,val); else insert(rc[k],x-L-1,val); if(a[rt[k]].sum*alpha>max(a[rt[lc[k]]].sum,a[rt[rc[k]]].sum)) { if(!tmp)return; if(lc[k]==tmp)rebuild(lc[k]);else rebuild(rc[k]); tmp=0; } else tmp=k; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&v[i]); for(int i=1;i<=n;i++)dfn[i]=i; build(root,1,n); scanf("%d",&m); char ch;int x,y,K; while(m--) { scanf(" %c%d%d",&ch,&x,&y); x^=ans;y^=ans; if(ch=='Q')scanf("%d",&K),K^=ans,printf("%d ",ans=solve(x,y,K)); else if(ch=='M')update(root,x,y); else{ tmp=0; insert(root,x-1,y); if(tmp)tmp=0,rebuild(root); } } }
长链剖分:https://www.luogu.org/problemnew/show/P4292
#include<bits/stdc++.h> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 using namespace std; const int N=2e5+7; int n,L,R,cnt,tot,hd[N],v[N],nxt[N],w[N],son[N],sv[N],dep[N],dfn[N]; double mid,ans,s[N<<2],val[N],f[N]; void add(int x,int y,int z){v[++tot]=y,nxt[tot]=hd[x],w[tot]=z,hd[x]=tot;} void dfs1(int u,int fa) { for(int i=hd[u];i;i=nxt[i]) if(v[i]!=fa) { dfs1(v[i],u); if(dep[v[i]]>=dep[son[u]])son[u]=v[i],sv[u]=w[i]; if(dep[v[i]]+1>dep[u])dep[u]=dep[v[i]]+1; } } void dfs2(int u,int fa) { dfn[u]=++cnt; if(son[u])dfs2(son[u],u); for(int i=hd[u];i;i=nxt[i])if(v[i]!=fa&&v[i]!=son[u])dfs2(v[i],u); } void update(int k,double v,int l,int r,int rt) { if(l==r){s[rt]=max(s[rt],v);return;} int mid=l+r>>1; if(k<=mid)update(k,v,lson);else update(k,v,rson); s[rt]=max(s[rt<<1],s[rt<<1|1]); } double query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R)return s[rt]; int mid=l+r>>1;double ret=-2e9; if(L<=mid)ret=max(ret,query(L,R,lson)); if(R>mid)ret=max(ret,query(L,R,rson)); return ret; } void dfs(int u,int fa) { int id=dfn[u]; if(son[u])dfs(son[u],u),val[id]=val[id+1]+sv[u]-mid; update(id,f[id]=-val[id],1,n,1); if(dep[u]>=L) { double tmp=query(id+L,id+min(dep[u],R),1,n,1); ans=max(ans,tmp+val[id]); } for(int i=hd[u];i;i=nxt[i]) if(v[i]!=fa&&v[i]!=son[u]) { int idv=dfn[v[i]]; dfs(v[i],u); for(int j=0;j<=dep[v[i]];j++) { int l=id+max(0,L-j-1),r=id+min(dep[u],R-j-1); double tmp=query(l,r,1,n,1); ans=max(ans,tmp+val[idv]+val[id]+f[idv+j]+w[i]-mid); } for(int j=0;j<=dep[v[i]];++j) { double tmp=val[idv]+f[idv+j]+w[i]-mid-val[id]; if(tmp>f[id+j+1])update(id+j+1,f[id+j+1]=tmp,1,n,1); } } } bool check() { for(int i=0;i<(N<<2);i++)s[i]=-2e9; ans=-2e9,dfs(1,0); return ans>=1e-4; } int main() { scanf("%d%d%d",&n,&L,&R); for(int i=1,x,y,z;i<n;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z); dfs1(1,0),dfs2(1,0); double l=0,r=1e6; while(r-l>1e-4) { mid=(l+r)/2; if(check())l=mid;else r=mid; } printf("%.3lf",l); }
fhq-treap:https://www.luogu.org/problemnew/show/CF702F
#include<bits/stdc++.h> using namespace std; const int N=2e5+7; int n,m,root,val[N],cnt[N],tv[N],tc[N],rd[N],ch[N][2]; pair<int,int>a[N]; void pushdown(int x) { if(!x)return; int lc=ch[x][0],rc=ch[x][1]; if(tv[x]) { val[lc]+=tv[x],val[rc]+=tv[x]; tv[lc]+=tv[x],tv[rc]+=tv[x]; tv[x]=0; } if(tc[x]) { cnt[lc]+=tc[x],cnt[rc]+=tc[x]; tc[lc]+=tc[x],tc[rc]+=tc[x]; tc[x]=0; } } void split(int rt,int&x,int&y,int v) { if(!rt){x=y=0;return;} pushdown(rt); if(val[rt]<v)x=rt,split(ch[rt][1],ch[x][1],y,v); else y=rt,split(ch[rt][0],x,ch[y][0],v); } int merge(int x,int y) { if(!x||!y)return x+y; if(rd[x]<rd[y]) { pushdown(x),ch[x][1]=merge(ch[x][1],y); return x; } else{ pushdown(y),ch[y][0]=merge(x,ch[y][0]); return y; } } int insert(int x,int y) { int r1=0,r2=0; split(x,r1,r2,val[y]); r1=merge(r1,y),x=merge(r1,r2); return x; } int dfs(int x,int y) { if(!x)return y; pushdown(x); y=dfs(ch[x][0],y),y=dfs(ch[x][1],y); ch[x][0]=ch[x][1]=0; return insert(y,x); } void down(int x) { if(!x)return; pushdown(x),down(ch[x][0]),down(ch[x][1]); } int main() { scanf("%d",&n); for(int i=1,x,y;i<=n;i++)scanf("%d%d",&x,&y),a[i]=make_pair(-y,x); sort(a+1,a+n+1); scanf("%d",&m); for(int i=1;i<=m;i++)scanf("%d",&val[i]),rd[i]=rand(),root=insert(root,i); for(int i=1;i<=n;i++) { int c=a[i].second,r1=0,r2=0,r3=0,r4=0; split(root,r1,r2,c); val[r2]-=c,tv[r2]-=c; cnt[r2]++,tc[r2]++; split(r2,r3,r4,c-1); r1=dfs(r3,r1),root=merge(r1,r4); } down(root); for(int i=1;i<=m;i++)printf("%d ",cnt[i]); }
笛卡尔树:https://www.luogu.org/problemnew/show/SP3734
#include<bits/stdc++.h> using namespace std; const int N=525,M=1e6+7,mod=1e9+7; int n,m,top,f[N][N],g[N],fac[M],inv[M],v[N],st[N],fa[N],ch[N][2]; int C(int a,int b){return a<b?0:1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;} int dfs(int x) { int a=1,b=v[x]-v[fa[x]],y,s; f[x][0]=1; for(int i=0;i<2;i++) if(ch[x][i]) { y=ch[x][i],s=dfs(y); memset(g,0,sizeof g); for(int j=0;j<=a;j++) for(int k=0;k<=s&&j+k<=m;k++) g[j+k]=(g[j+k]+1ll*f[x][j]*f[y][k])%mod; a+=s; for(int j=0;j<=a;j++)f[x][j]=g[j]; } for(int i=min(m,a);~i;i--) { s=0; for(int j=0;j<=i;j++)s=(s+1ll*f[x][i-j]*fac[j]%mod*C(a-i+j,j)%mod*C(b,j))%mod; f[x][i]=s; } return a; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&v[i]); fac[0]=1;for(int i=1;i<M;i++)fac[i]=1ll*fac[i-1]*i%mod; inv[0]=inv[1]=1;for(int i=2;i<M;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod; for(int i=2;i<M;i++)inv[i]=1ll*inv[i-1]*inv[i]%mod; for(int i=1;i<=n;i++) { while(top&&v[st[top]]>v[i]) { int x=st[top--]; if(top&&v[st[top]]>v[i])ch[st[top]][1]=x,fa[x]=st[top]; else ch[i][0]=x,fa[x]=i; } st[++top]=i; } while(top>1)ch[st[top-1]][1]=st[top],fa[st[top]]=st[top-1],top--; dfs(st[1]); printf("%d",f[st[1]][m]); }
树套树:https://www.lydsy.com/JudgeOnline/problem.php?id=3489
#include<bits/stdc++.h> #define lson l,mid,ch[rt][0] #define rson mid+1,r,ch[rt][1] using namespace std; const int N=1e5+7,M=4e7+7; typedef long long ll; struct node{int x,y,z,v;}; int n,m,tot,ans,a[N],pre[N],nxt[N],lst[N],rt[N],ch[M][2],v[M]; node p[N]; bool operator<(node x,node y){return x.x<y.x;} void change(int prt,int l,int r,int&rt,node c) { rt=++tot; memcpy(ch[rt],ch[prt],sizeof ch[rt]); v[rt]=max(v[prt],c.v); if(l==r)return; int mid=l+r>>1; if(c.z<=mid)change(ch[prt][0],lson,c); else change(ch[prt][1],rson,c); } void modify(int prt,int l,int r,int&rt,node c) { rt=++tot; memcpy(ch[rt],ch[prt],sizeof ch[rt]); change(v[prt],1,n+2,v[rt],c); if(l==r)return; int mid=l+r>>1; if(c.y<=mid)modify(ch[prt][0],lson,c); else modify(ch[prt][1],rson,c); } int ask(int L,int R,int l,int r,int rt) { if(!rt)return 0; if(L<=l&&r<=R)return v[rt]; int mid=l+r>>1,ret=0; if(L<=mid)ret=max(ret,ask(L,R,lson)); if(R>mid)ret=max(ret,ask(L,R,rson)); return ret; } int query(int L,int R,int l,int r,int rt,int ql,int qr) { if(!rt)return 0; if(L<=l&&r<=R)return ask(ql,qr,1,n+2,v[rt]); int mid=l+r>>1,ret=0; if(L<=mid)ret=max(ret,query(L,R,lson,ql,qr)); if(R>mid)ret=max(ret,query(L,R,rson,ql,qr)); return ret; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)lst[i]=1; for(int i=2;i<=n+1;i++)scanf("%d",&a[i]),nxt[lst[a[i]]]=i,pre[i]=lst[a[i]],lst[a[i]]=i; for(int i=1;i<=n;i++)nxt[lst[i]]=n+2; for(int i=2;i<=n+1;i++)p[i-1]=(node){pre[i],nxt[i],i,a[i]}; sort(p+1,p+n+1); for(int i=1,pos=1;i<=n+2;i++) { rt[i]=rt[i-1]; while(p[pos].x==i&&pos<=n)modify(rt[i],1,n+2,rt[i],p[pos++]); } while(m--) { int x,y,l,r; scanf("%d%d",&x,&y); x=(x+ans)%n+2,y=(y+ans)%n+2,l=min(x,y),r=max(x,y); printf("%d ",ans=query(r+1,n+2,1,n+2,rt[l-1],l,r)); } }
LCT:https://www.luogu.org/problemnew/show/P3203
#include<cstdio> #include<algorithm> using namespace std; const int N=2e5+7; int n,fa[N],ch[N][2],nxt[N],st[N],sz[N],rev[N]; bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} void pushup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;} void pushdown(int x) { int l=ch[x][0],r=ch[x][1]; if(rev[x])rev[x]^=1,rev[l]^=1,rev[r]^=1,swap(ch[x][0],ch[x][1]); } void rotate(int x) { int y=fa[x],z=fa[fa[x]],l; l=(ch[y][1]==x); 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][l^1]]=y; ch[y][l]=ch[x][l^1],ch[x][l^1]=y; pushup(y),pushup(x); } void splay(int x) { st[1]=x; int top=1; for(int i=x;!isroot(i);i=fa[i])st[++top]=fa[i]; for(int i=top;i;i--)pushdown(st[i]); while(!isroot(x)) { int y=fa[x],z=fa[fa[x]]; if(!isroot(y)) { if((ch[y][0]==x)^(ch[z][0]==y))rotate(x); else rotate(y); } rotate(x); } } void access(int x) { int t=0; while(x)splay(x),ch[x][1]=t,t=x,x=fa[x]; } void reverse(int x){access(x),splay(x),rev[x]^=1;} void link(int x,int y){reverse(x),fa[x]=y,splay(x);} void cut(int x,int y){reverse(x),access(y),splay(y),ch[y][0]=fa[x]=0;} int main() { scanf("%d",&n); int op,x,y,Q; for(int i=1;i<=n;i++)scanf("%d",&x),fa[i]=min(x+i,n+1),sz[i]=1,nxt[i]=fa[i]; sz[n+1]=1; scanf("%d",&Q); while(Q--) { scanf("%d%d",&op,&x); x++; if(op==1)reverse(n+1),access(x),splay(x),printf("%d ",sz[ch[x][0]]); else scanf("%d",&y),cut(x,nxt[x]),link(x,min(x+y,n+1)),nxt[x]=min(x+y,n+1); } }
KD-Tree:https://www.lydsy.com/JudgeOnline/problem.php?id=2850
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=50010,inf=2e9; struct Node{int mx[2],mn[2],d[2],lc,rc,v;ll s;}t[maxn],x; int D,n,m,rt,a,b,c; bool operator<(Node a,Node b){return a.d[D]<b.d[D];} void update(int k) { t[k].s=t[t[k].lc].s+t[t[k].rc].s+t[k].v; for(int i=0;i<2;i++) { t[k].mn[i]=min(min(t[t[k].lc].mn[i],t[t[k].rc].mn[i]),t[k].d[i]); t[k].mx[i]=max(max(t[t[k].lc].mx[i],t[t[k].rc].mx[i]),t[k].d[i]); } } void build(int&k,int l,int r,int cur) { k=0; if(l>r)return; D=cur; int mid=(l+r)/2; nth_element(t+l,t+mid,t+r+1); k=mid; build(t[k].lc,l,mid-1,cur^1); build(t[k].rc,mid+1,r,cur^1); update(k); } bool inner(int x,int y){return 1ll*a*x+1ll*b*y<c;} int check(int k) { int cnt=0; if(inner(t[k].mn[0],t[k].mn[1]))cnt++; if(inner(t[k].mn[0],t[k].mx[1]))cnt++; if(inner(t[k].mx[0],t[k].mn[1]))cnt++; if(inner(t[k].mx[0],t[k].mx[1]))cnt++; if(!cnt)return 0; if(cnt==4)return 1; return -1; } ll query(int k) { if(!k)return 0; int f=check(k); if(!f)return 0; if(f==1)return t[k].s; return query(t[k].lc)+query(t[k].rc)+t[k].v*inner(t[k].d[0],t[k].d[1]); } int main() { scanf("%d%d",&n,&m); t[0].mn[0]=t[0].mn[1]=1e9; t[0].mx[0]=t[0].mx[1]=-1e9; for(int i=1;i<=n;i++)scanf("%d%d%d",&t[i].d[0],&t[i].d[1],&t[i].v); build(rt,1,n,0); while(m--)scanf("%d%d%d",&a,&b,&c),printf("%lld ",query(rt)); }
线段树优化建图:https://www.luogu.org/problemnew/show/CF786B
#include<bits/stdc++.h> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 typedef long long ll; using namespace std; typedef pair<int,int>pii; const int N=1e5+7; struct node{int u;ll d;}; int n,m,S,tot,id[2][N<<2],vis[N*5]; ll d[N*5]; vector<pii>G[N*5]; vector<int>vec; bool operator<(node a,node b){return a.d>b.d;} priority_queue<node>q; void adde(int u,int v,int w){G[u].push_back(pii(v,w));} void build(int l,int r,int rt,int k) { id[k][rt]=++tot; if(l==r) { if(!k)adde(id[k][rt],l,0);else adde(l,id[k][rt],0); return; } int mid=l+r>>1; build(lson,k),build(rson,k); if(!k)adde(id[k][rt],id[k][rt<<1],0),adde(id[k][rt],id[k][rt<<1|1],0); else adde(id[k][rt<<1],id[k][rt],0),adde(id[k][rt<<1|1],id[k][rt],0); } void query(int L,int R,int k,int l,int r,int rt) { if(L<=l&&r<=R){vec.push_back(id[k][rt]);return;} int mid=l+r>>1; if(L<=mid)query(L,R,k,lson); if(R>mid)query(L,R,k,rson); } void dijkstra(int S) { for(int i=1;i<=5*n;i++)d[i]=1e18,vis[i]=0; q.push((node){S,0}),d[S]=0; while(!q.empty()) { int u=q.top().u;q.pop(); if(vis[u])continue; vis[u]=1; for(int i=0;i<G[u].size();i++) { int v=G[u][i].first,w=G[u][i].second; if(d[v]>d[u]+w)d[v]=d[u]+w,q.push((node){v,d[v]}); } } } int main() { scanf("%d%d%d",&n,&m,&S); tot=n; build(1,n,1,0),build(1,n,1,1); while(m--) { int op,x,l,r,w;scanf("%d%d%d",&op,&x,&l); if(op==1)scanf("%d",&w),adde(x,l,w); else if(op==2) { vec.clear(); scanf("%d%d",&r,&w); query(l,r,0,1,n,1); for(int i=0;i<vec.size();i++)adde(x,vec[i],w); } else{ vec.clear(); scanf("%d%d",&r,&w); query(l,r,1,1,n,1); for(int i=0;i<vec.size();i++)adde(vec[i],x,w); } } dijkstra(S); for(int i=1;i<=n;i++)if(d[i]==1e18)printf("-1 ");else printf("%lld ",d[i]); }
暂时没了。