[bzoj3282]Tree (lct)
昨天看了一天的lct。。当然幸好最后看懂了(也许吧。。)
论善良学长的重要性T_T,老司机带带我!
这题主要是删边的时候还要判断一下。。蒟蒻一开始天真的以为存在的边才能删结果吃了一发wa。。。
事实是只要两个点之间联通就能断开了,管它有没有边。。。。整个就一模板题。。
交上去后跑得很慢(记录类型的锅)。。但还是很短?(请自行无视过长变量名)
- #include<cstdio>
- #include<math.h>
- #include<iostream>
- #include<algorithm>
- using namespace std;
- const int maxn=;
- struct zs{
- int c[],fa,val,sum;
- bool rev;
- }tree[maxn];
- int i,j,n,m,id,x,y;
- int stack[maxn];
- inline void update(int x){tree[x].sum=tree[tree[x].c[]].sum^tree[x].val^tree[tree[x].c[]].sum;
- }
- inline bool isroot(int x){return tree[tree[x].fa].c[]!=x&&tree[tree[x].fa].c[]!=x;
- }
- void rotate(int x){
- int fa=tree[x].fa,gfa=tree[fa].fa;
- if(!isroot(fa))tree[gfa].c[tree[gfa].c[]==fa]=x;
- int l=tree[fa].c[]==x,r=l^;
- tree[fa].c[l]=tree[x].c[r];tree[x].c[r]=fa;
- tree[fa].fa=x;tree[x].fa=gfa;tree[tree[fa].c[l]].fa=fa;
- update(fa);update(x);
- }
- void pushdown(int x){
- if(!tree[x].rev)return;
- int l=tree[x].c[],r=tree[x].c[];
- if(l)tree[l].rev^=;if(r)tree[r].rev^=;
- swap(tree[x].c[],tree[x].c[]);tree[x].rev^=;
- }
- void splay(int x){
- int top=,tmp=x;stack[++top]=x;
- while(!isroot(tmp))stack[++top]=tree[tmp].fa,tmp=tree[tmp].fa;
- while(top)pushdown(stack[top]),top--;
- int fa,gfa;
- while(!isroot(x)){
- fa=tree[x].fa,gfa=tree[fa].fa;
- if(!isroot(fa))
- if((tree[gfa].c[]==fa)^(tree[fa].c[]==x))rotate(x);
- else rotate(fa);
- rotate(x);
- }
- }
- void access(int x){
- int son=;
- while(x){
- splay(x);tree[x].c[]=son;
- update(x);
- son=x;x=tree[x].fa;
- }
- }
- void makeroot(int x){
- access(x);splay(x);tree[x].rev^=;
- }
- void link(int x,int y){
- makeroot(x);tree[x].fa=y;splay(x);
- }
- void cut(int x,int y){
- makeroot(x);access(y);splay(y);tree[y].c[]=tree[x].fa=;
- }
- int query(int x,int y){
- makeroot(x);access(y);splay(y);return tree[y].sum;
- }
- int getfa(int x){
- access(x);splay(x);while(tree[x].c[])pushdown(x),x=tree[x].c[];splay(x);
- return x;
- }
- void change(int x,int y){
- makeroot(x);tree[x].val=y;update(x);
- }
- int main(){
- scanf("%d%d",&n,&m);
- for(i=;i<=n;i++)scanf("%d",&tree[i].val),tree[i].sum=tree[i].val;
- while(m--){
- scanf("%d%d%d",&id,&x,&y);
- if(id==)printf("%d\n",query(x,y));
- else if(id==){if(getfa(x)!=getfa(y))link(x,y);}
- else if(id==){if(getfa(x)==getfa(y))cut(x,y);}
- else if(id==)change(x,y);
- }
- return ;
- }
b站上的lct怎么都是300大洋的世界。。
16.1.13:重写了一发
- #include<cstdio>
- #include<iostream>
- #include<cstring>
- using namespace std;
- const int maxn=;
- int ch[maxn][],fa[maxn],sum[maxn],num[maxn],st[maxn];
- bool rev[maxn];
- int i,j,n,m,x,y;
- int ra;char rx;
- inline int read(){
- rx=getchar(),ra=;
- while(rx<''||rx>'')rx=getchar();
- while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra;
- }
- char s[];
- inline void outx(int x){
- if(!x)putchar('');
- register int len=;
- while(x)s[++len]=x%,x/=;
- while(len)putchar(s[len--]+);putchar('\n');
- }
- inline bool isrt(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
- inline void upd(int x){sum[x]=sum[ch[x][]]^num[x]^sum[ch[x][]];}
- inline void pushdown(int x){
- if(!rev[x])return;
- rev[x]=,swap(ch[x][],ch[x][]),rev[ch[x][]]^=,rev[ch[x][]]^=;
- }
- inline void rotate(int x){
- int f=fa[x],gfa=fa[f],l=ch[f][]==x,r=l^;
- if(!isrt(f))ch[gfa][ch[gfa][]==f]=x;
- fa[x]=gfa,fa[f]=x,ch[f][l]=ch[x][r],ch[x][r]=f,fa[ch[f][l]]=f;
- sum[x]=sum[f],upd(f);
- }
- void splay(int x){
- int f,gfa;
- for(st[st[]=]=f=x;!isrt(f);)st[++st[]]=(f=fa[f]);
- while(st[])pushdown(st[st[]--]);
- for(f=fa[x],gfa=fa[f];!isrt(x);rotate(x),f=fa[x],gfa=fa[f])
- if(!isrt(f))rotate(((ch[f][]==x)^(ch[gfa][]==f))?x:f);
- }
- inline void access(int x){
- for(int t=;x;t=x,x=fa[x])splay(x),ch[x][]=t,upd(x);
- }
- inline void makert(int x){
- access(x),splay(x),rev[x]^=;
- }
- void cut(int x,int y){
- makert(x),access(y),splay(y),ch[y][]=fa[x]=,upd(y);
- }
- void link(int x,int y){
- makert(x),fa[x]=y;if(!(x&))splay(x);
- }
- inline int query(int x,int y){
- makert(x),access(y),splay(y);
- return sum[y];
- }
- inline int getfa(int x){
- for(access(x),splay(x),pushdown(x);ch[x][];x=ch[x][]);
- return x;
- }
- inline void change(int x,int v){
- splay(x),num[x]=v,upd(x);
- }
- int main(){
- n=read(),m=read();
- for(i=;i<=n;i++)num[i]=read();int id;
- while(m--){
- id=read(),x=read(),y=read();
- if(id==)outx(query(x,y));
- if(id==)if(getfa(x)!=getfa(y))link(x,y);
- if(id==)if(getfa(x)==getfa(y))cut(x,y);
- if(id==)change(x,y);
- }
- return ;
- }
3282: Tree
Time Limit: 30 Sec Memory Limit: 512 MB
Description
给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。
0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点X上的权值变成Y。
Input
第1行两个整数,分别为N和M,代表点数和操作数。
第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。
第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。
Output
对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。
Sample Input
1
2
3
1 1 2
0 1 2
0 1 1
Sample Output
1
HINT
1<=N,M<=300000
[bzoj3282]Tree (lct)的更多相关文章
- BZOJ3282: Tree (LCT模板)
Description 给定N个点以及每个点的权值,要你处理接下来的M个操作. 操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和 ...
- 【BZOJ3282】Tree LCT
1A爽,感觉又对指针重怀信心了呢= =,模板题,注意单点修改时splay就好,其实按吾本意是没写的也A了,不过应该加上能更好维护平衡性. ..还是得加上好= = #include <iostre ...
- BZOJ3282: Tree
传送门 又是权限题= =,过了NOIp我就要去当一只权限狗! LCT裸题,get到了两个小姿势. 1.LCA操作应该在access中随时updata 2.Link操作可以更简单 void Link(i ...
- BZOJ-3282 Tree Link-Cut-Tree(似乎树链剖分亦可)
蛋蛋用链剖A的,我写的LCT 3282: Tree Time Limit: 30 Sec Memory Limit: 512 MB Submit: 1241 Solved: 542 [Submit][ ...
- HDU 5002 Tree LCT 区间更新
Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action?c ...
- hdu5398 GCD Tree(lct)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud GCD Tree Time Limit: 5000/2500 MS (Java/O ...
- BZOJ 3282: Tree( LCT )
LCT.. -------------------------------------------------------------------------------- #include<c ...
- BZOJ 2631: tree( LCT )
LCT...略麻烦... -------------------------------------------------------------------------------- #inclu ...
- Link-Cut Tree(LCT)&TopTree讲解
前言: Link-Cut Tree简称LCT是解决动态树问题的一种数据结构,可以说是我见过功能最强大的一种树上数据结构了.在此与大家分享一下LCT的学习笔记.提示:前置知识点需要树链剖分和splay. ...
随机推荐
- ios 中的循环引用问题及解决
循环引用,指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存.其实有点类似死锁. 举个例子:A->B->C->....->X->B - ...
- springboot学习(一)——helloworld
以下内容,如有问题,烦请指出,谢谢 springboot出来也很久了,以前零散地学习了不少,不过很长时间了都没有在实际中使用过了,忘了不少,因此要最近准备抽时间系统的学习积累下springboot,给 ...
- Linux服务器上的oracle数据导入和导出
背景: 在同一台Linux服务器上,有两个数据库用户,分别为:database1,database2,如何把database1用户下面的所有的表和数据,导入到database2数据库(database ...
- FPGA设计思想与技巧(转载)
题记:这个笔记不是特权同学自己整理的,特权同学只是对这个笔记做了一下完善,也忘了是从那DOWNLOAD来的,首先对整理者表示感谢.这些知识点确实都很实用,这些设计思想或者也可以说是经验吧,是很值得每一 ...
- Webpack 2 视频教程 008 - WDS 端口号等配置相关
原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...
- JavaScript的DOM编程--07--节点的属性
节点的属性: 1). nodeName: 代表当前节点的名字. 只读属性. 如果给定节点是一个文本节点, nodeName 属性将返回内容为 #text 的字符串 2). nodeType:返回一个整 ...
- popupwindow那些坑
1. new PopupWindow(vw, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 如果 ...
- 安卓和 java 学习笔记
1.访问权限为 private 的成员变量或方法,需要执行setAccessible() 方法,并将入口参数设置为 true; 否则不允许访问. 2.为了保证线程的安全,可以使用同步块 synchro ...
- Head First设计模式之原型模式
一.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式.在实际应用中,原型模式很少单独出现 ...
- angular4.0项目main.ts详解
main.ts负责引导整个angular应用的起点 // 导入enableProdMode用来关闭angular开发者模式 import { enableProdMode } from '@angul ...