您的位置:首页 > 其它

UOJ_274_[清华集训2016]温暖会指引我们前行_LCT

2018-05-20 10:39 405 查看

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

[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 [2],f ,sum ,mn ,t ,l ,rev ,n,m,xx ,yy ,fa ; 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\n",ans); }else { id=rd(); z=rd(); id++; access(id+n); splay(id+n); l[id+n]=z; pushup(id+n); } } }

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: