UOJ_274_[清华集训2016]温暖会指引我们前行_LCT
任务描述:http://uoj.ac/problem/274
本题中的字典序不同在于空串的字典序最大。
并且题中要求排序后字典序最大。
因此我们要求的路径一定是最大生成树上的路径。
于是变成了LCT模板题,动态维护最大生成树即可。
注意每次find可能会T,于是我又写了个并查集...
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define RR register inline char nc() { static char buf[100000],*p1,*p2; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int rd() { RR int x=0; RR char s=nc(); while(s<'0'||s>'9') s=nc(); while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc(); return x; } inline char rc() { RR char s=nc(); while(s<'a'||s>'z') s=nc(); return s; } #define ls ch[p][0] #define rs ch[p][1] #define get(x) (ch[f[x]][1]==x) #define isrt(x) (ch[f[x]][1]!=x&&ch[f[x]][0]!=x) #define N 1000050 int ch[N][2],f[N],sum[N],mn[N],t[N],l[N],rev[N],n,m,xx[N],yy[N],fa[N]; char opt[10]; int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); } inline void pushup(int p) { sum[p]=sum[ls]+sum[rs]+l[p]; mn[p]=p; if(t[mn[ls]]<t[mn[p]]) mn[p]=mn[ls]; if(t[mn[rs]]<t[mn[p]]) mn[p]=mn[rs]; } inline void pushdown(int p) { if(rev[p]) { swap(ch[ls][0],ch[ls][1]); swap(ch[rs][0],ch[rs][1]); rev[ls]^=1; rev[rs]^=1; rev[p]=0; } } void rotate(int x) { int y=f[x],z=f[y],k=get(x); if(!isrt(y)) ch[z][ch[z][1]==y]=x; ch[y][k]=ch[x][!k]; f[ch[y][k]]=y; ch[x][!k]=y; f[y]=x; f[x]=z; pushup(y); pushup(x); } void update(int p) { if(!isrt(p)) update(f[p]); pushdown(p); } void splay(int x) { update(x); for(int fa;fa=f[x],!isrt(x);rotate(x)) if(!isrt(fa)) rotate(get(fa)==get(x)?fa:x); } void access(int p) { int t=0; while(p) { splay(p); rs=t; pushup(p); t=p; p=f[p]; } } void makeroot(int p) { access(p); splay(p); swap(ls,rs); rev[p]^=1; } void link(int x,int p) { makeroot(x); splay(p); f[x]=p; } void cut(int x,int p) { makeroot(x); access(p); splay(p); f[x]=ls=0; } int querymin(int x,int p) { makeroot(x); access(p); splay(p); return mn[p]; } int qlen(int x,int p) { makeroot(x); access(p); splay(p); return sum[p]; } int main() { n=rd(); m=rd(); int i,x,y,z,w,id; for(i=0;i<=n;i++) t[i]=1<<30,mn[i]=i,fa[i]=i; while(m--) { opt[0]=rc(); if(opt[0]=='f') { id=rd(); x=rd(); y=rd(); z=rd(); w=rd(); id++; x++; y++; t[id+n]=z; l[id+n]=w; mn[id+n]=id+n; xx[id]=x; yy[id]=y; int dx=find(x),dy=find(y); if(dx==dy) { int tmp=querymin(x,y); if(t[tmp]>=z) continue; cut(xx[tmp-n],tmp); cut(yy[tmp-n],tmp); }else fa[dx]=dy; link(id+n,x); link(id+n,y); }else if(opt[0]=='m') { x=rd(); y=rd(); x++; y++; int ans=find(x)==find(y)?qlen(x,y):-1; printf("%d ",ans); }else { id=rd(); z=rd(); id++; access(id+n); splay(id+n); l[id+n]=z; pushup(id+n); } } }