[bzoj2816][ZJOI2012]网络(LCT,splay)
题解
话说以前还真没见过用LCT只维护一条链的……好像除了树点涂色那题……
先看一下题目规定的两个性质
对于任意节点连出去的边中,相同颜色的边不超过两条。
图中不存在同色的环,同色的环指相同颜色的边构成的环。
很明显了,同一种颜色肯定是由几条链组成的(虽然我根本没有发现)
然后又要查询边权和维护路径……直接上LCT吧
然后颜色数很少啊……每一个颜色开一个LCT好了
更改权值的话在每一个LCT上splay一下
修改颜色的话在原来的LCT中cut,新的LCT中link
查询路径直接split出来
然后差不多就这样了
//minamoto
#include<cstdio>
#include<map>
#include<iostream>
using std::swap;
using std::map;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=;
int n,m,val[N],c,k;
struct link_cut_tree{
int fa[N],ch[N][],rev[N],mx[N],cnt[N],s[N],top;
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline void pushup(int x){
mx[x]=val[x];int l=ch[x][],r=ch[x][];
if(l) cmax(mx[x],mx[l]);
if(r) cmax(mx[x],mx[r]);
}
inline void pushdown(int x){
if(x&&rev[x]){
swap(ch[x][],ch[x][]);
rev[ch[x][]]^=,rev[ch[x][]]^=;
rev[x]=;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,pushup(y);
}
void splay(int x){
s[top=]=x;for(int i=x;!isroot(i);i=fa[i]) s[++top]=fa[i];
while(top) pushdown(s[top--]);
for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
if(!isroot(y))
((ch[y][]==x)^(ch[z][]==y))?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=;x;x=fa[y=x])
splay(x),ch[x][]=y,pushup(x);
}
void makeroot(int x){
access(x),splay(x),rev[x]^=;
}
void split(int x,int y){
makeroot(x),access(y),splay(y);
}
inline void link(int x,int y){
++cnt[x],++cnt[y],makeroot(x),fa[x]=y,splay(x);
}
inline void cut(int x,int y){
--cnt[x],--cnt[y],split(x,y),fa[x]=ch[y][]=,pushup(y);
}
int findroot(int x){
access(x),splay(x),pushdown(x);
while(ch[x][]) pushdown(x=ch[x][]);
return x;
}
inline int query(int x,int y){
split(x,y);return mx[y];
}
}lct[];
struct edge{
int u,v;
inline bool operator <(const edge &b)const
{return u<b.u||(u==b.u&&v<b.v);}
};
map<edge,int> mp;
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read(),c=read(),k=read();
for(int i=;i<=n;++i) val[i]=read();
for(int i=;i<=m;++i){
int u=read(),v=read(),w=read();
edge e1=(edge){u,v},e2=(edge){v,u};
mp[e1]=mp[e2]=w;
lct[w].link(u,v);
}
while(k--){
int opt=read();
switch(opt){
case :{
int x=read(),w=read();
val[x]=w;
for(int i=;i<c;++i) lct[i].splay(x);
break;
}
case :{
int u=read(),v=read(),w=read();
edge a=(edge){u,v},b=(edge){v,u};
if(!mp.count(a)){puts("No such edge.");continue;}
int x=mp[a];
if(x==w){puts("Success.");continue;}
if(lct[w].cnt[u]>=||lct[w].cnt[v]>=){puts("Error 1.");continue;}
if(lct[w].findroot(u)==lct[w].findroot(v)){puts("Error 2.");continue;}
puts("Success.");
lct[x].cut(u,v),lct[w].link(u,v);
mp[a]=mp[b]=w;
break;
}
case :{
int w=read(),u=read(),v=read();
if(lct[w].findroot(u)!=lct[w].findroot(v)){puts("-1");continue;}
printf("%d\n",lct[w].query(u,v));
break;
}
}
}
return ;
}
[bzoj2816][ZJOI2012]网络(LCT,splay)的更多相关文章
- BZOJ2816:[ZJOI2012]网络(LCT)
Description 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构 ...
- bzoj 2816: [ZJOI2012]网络 (LCT 建多棵树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2816 题面: http://www.lydsy.com/JudgeOnline/upload ...
- bzoj2816 [ZJOI2012]网络
Description http://www.lydsy.com/JudgeOnline/upload/zjoi2012.pdf 正解:$link-cut \ tree$. $LCT$板子题,直接维护 ...
- BZOJ.2816.[ZJOI2012]网络(LCT)
题目链接 BZOJ 洛谷 对每种颜色维护一个LCT,保存点之间的连接关系. 修改权值A[x]和所有Max[x]都要改: 修改边的颜色先枚举所有颜色,看是否在某种颜色中有边,然后断开.(枚举一遍就行啊 ...
- Luogu 2173 [ZJOI2012]网络 - LCT
Solution $LCT$ 直接上$QuQ$ 注意$cut$ 完 需要 $d[u + c * N]--$ 再 $link$, 不然会输出Error 1的哦 Code #include<cs ...
- bzoj千题计划223:bzoj2816: [ZJOI2012]网络
http://www.lydsy.com/JudgeOnline/problem.php?id=2816 每种颜色搞一个LCT 判断u v之间有边直接相连: 如果u和v之间有边相连,那么他们的深度相差 ...
- ZJOI2012 网络——LCT相关题目
有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构成的环. 在这个图上,你 ...
- luoguP2173 [ZJOI2012]网络 LCT
链接 luogu 思路 颜色很少,开10个lct分别维护 if (Hash.count(make_pair(u, v)) && Hash[make_pair(u, v)] == col ...
- bzoj 2816: [ZJOI2012]网络(splay)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2816 [题意] 给定一个无向图,满足条件:从一个节点出发的同色边不超过2条,且不存在同 ...
随机推荐
- mysql-5.6.24-win32解决没有my.ini并且修改编码
3.配置环境变量:新建一个系统变量: MYSQL_HOME, 值:D:\MySql\mysql5611 //这一步不做也行 4.修改MySql启动配置文件: 将安装目录下文件:my-default. ...
- RedHat Linux设置yum软件源为本地ISO
先挂载ISO到某个目录下(如我的:/media/RHEL_6.0 x86_64 Disc 1) # mount –o loop rhel-server-6.4-x86_64-dvd.iso /medi ...
- Linux 下启动两个tomcat
Linux 下启动两个tomcat 闲来无事学习nginx,想要配置个load balance.可是先决条件是:得有两个web容器.两个电脑是不用想了.只能想办法在一个机器上启动两个tomcat.原以 ...
- CentOS 6.4一键自动化安装ISO镜像光盘
下载CentOS-6.4-x86_64-minimal.iso 1 http://mirrors.163.com/centos/6.4/isos/x86_64/CentOS-6.4-x86_64-mi ...
- 浅谈利用PLSQL的多线程处理机制,加快处理大数据表的效率
我们在处理大数据表的时候经常会感觉的处理速度不够快,效率不够高,那么今天下面我就来简单实现下PLSQL的多线程编程处理数据: 我模拟一个简单的场景,把某一张表中的数据(当然这张表的数据非常大)同步到目 ...
- 浅谈c/c++中的指针问题
首先给出几种指针类型来作出区分,不看后面的解析如果可以自己分辨正确那么就算对指针有一个很好的掌握了,就没有必要再去看后面的解析,如果不能完全区分,那么就有必要仔细看看后面解析. 1 Char * p ...
- CF 438E The Child and Binary Tree
BZOJ 3625 吐槽 BZOJ上至今没有卡过去,太慢了卡得我不敢交了…… 一件很奇怪的事情就是不管是本地还是自己上传数据到OJ测试都远远没有到达时限. 本题做法 设$f_i$表示权值为$i$的二叉 ...
- 1710 生日蛋糕(1999 noi)
1710 生日蛋糕(1999 noi) 1999年NOI全国竞赛 题目描述 Description 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体 ...
- linux 下删除乱码文件-乾颐堂
在linux下删除文件,遇到特殊字符是一件非常头疼的事情. 1. 如果文件名带 ‘-’ 或者‘--’这样的字符 删除办法为:rm -- 文件名 如文件名为:-pythontab.tgz 如果用普通方法 ...
- [Training Video - 4] [Groovy] Function in detail
Employee.log=log Employee e1 = new Employee() Employee e2 = new Employee() e1.name = "A" e ...