您的位置:首页 > 其它

uoj#274. 【清华集训2016】温暖会指引我们前行 //LCT

2017-12-25 08:48 447 查看
uoj#274.【清华集训2016】温暖会指引我们前行

题意

N≤1e5个点,M≤3e5个操作。

每条边有一个权值T(保证互异)和一个长度L,资磁加边、改变一条边的L、询问u到v在关于T的最大生成树上的路径长度。

题解

这题主要难度大概都在读题上…。

lct模板题我怎么整天写模板题啊,维护一下最大生成树即可。

txl学长说那个高级的边权lct写法并不比拆点优越到哪里去…所以写了一发边拆点的lct 感觉并不很麻烦嘛

代码

UPD:原来那个直接getroot的被negii hack掉了…

不splay的话复杂度的确会炸

然后我lct好像以前一直是那么写的…。太可怕了(

#include<bits/stdc++.h>
#define N 200005
#define M 300005
#define pf(x) (c[f[x]][0]==x||c[f[x]][1]==x)
using namespace std;
int n,m,tem
,len
,mn
,sl
,cct;
int id[M],di[N],c[N][2],f
;
bool rev
;
inline void reverse(int x)
{rev[x]^=1,swap(c[x][0],c[x][1]);}
inline void pushdown(int x)
{if(rev[x])rev[x]=0,reverse(c[x][0]),reverse(c[x][1]);}
void pd(int x)
{if(pf(x))pd(f[x]);pushdown(x);}
inline void update(int x)
{
mn[x]=x,sl[x]=len[x];
if(c[x][0])sl[x]+=sl[c[x][0]],
mn[x]=tem[mn[x]]>tem[mn[c[x][0]]]?mn[c[x][0]]:mn[x];
if(c[x][1])
sl[x]+=sl[c[x][1]],
mn[x]=tem[mn[x]]>tem[mn[c[x][1]]]?mn[c[x][1]]:mn[x];
}
inline void rotate(int x,bool t)
{
int y=f[x];
if(pf(y))c[f[y]][c[f[y]][1]==y]=x;
f[x]=f[y],f[y]=x,f[c[x][t]]=y;
c[y][t^1]=c[x][t],c[x][t]=y;
update(y),update(x);
}
inline void splay(int x)
{
pd(x);
int y;bool t1,t2;
while(pf(x))
{
t1=c[y=f[x]][0]==x,t2=c[f[y]][0]==y;
if(!pf(y)){rotate(x,t1);return;}
if(t1^t2)rotate(x,t1),rotate(x,t2);
else rotate(y,t2),rotate(x,t1);
}
}
inline void access(int x)
{
int y=0;
while(x)
splay(x),c[x][1]=y,update(x),
y=x,x=f[x];
}
inline void exroot(int x)
{access(x);splay(x);reverse(x);}
inline int getroot(int x)
{
pushdown(x);
while(c[x][0])
x=c[x][0],pushdown(x);
splay(x);
return x;
}
char op[10];
int d,u,v,t,l,w;
int main()
{
scanf("%d%d",&n,&m),cct=n;
for(int i=1;i<=n;i++)
tem[i]=2e9,update(i);
while(m--)
{
scanf("%s",op);
if(op[0]=='f')
{
scanf("%d%d%d%d%d",&d,&u,&v,&t,&l);
u++,v++;
exroot(u),access(v),splay(v),w=mn[v];
if(getroot(v)==u)
{
if(tem[w]<t)
{
splay(w),f[c[w][0]]=f[c[w][1]]=0;
c[w][0]=c[w][1]=0;
id[di[w]]=-1;
}
else {id[d]=-1;continue;}
}
else w=++cct;
tem[w]=t,len[w]=l,id[d]=w,di[w]=d;
update(w);
exroot(u),f[u]=w;exroot(w),f[w]=v;
}
if(op[0]=='m')
{
scanf("%d%d",&u,&v);u++,v++;
exroot(u);
access(v),splay(v),w=sl[v];
printf("%d\n",(getroot(v)^u)?-1:w);
}
if(op[0]=='c')
{
scanf("%d%d",&d,&l);
if(id[d]^-1)
splay(id[d]),len[id[d]]=l,update(id[d]);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: