当前位置: 首页 > news >正文

QTREE5 - Query on a tree V(LCT)

题意翻译

你被给定一棵n个点的树,点从1到n编号。每个点可能有两种颜色:黑或白。我们定义dist(a,b)为点a至点b路径上的边个数。

一开始所有的点都是黑色的。

要求作以下操作:

0 i 将点i的颜色反转(黑变白,白变黑)

1 v 询问dist(u,v)的最小值。u点必须为白色(u与v可以相同),显然如果v是白点,查询得到的值一定是0。

特别地,如果作'1'操作时树上没有白点,输出-1。

题解

是QTREE4的弱化版诶……

具体的思路可以看看Qtree4的->这里

注意把求最大改成求最小,还有只需要到点的最短距离,不需要维护子树里的答案了

然后查询的时候本来打算makeroot的……后来发现太麻烦了……直接access+splay,然后查询rmx即可(因为已经在这个splay里深度最大了)

  1 //minamoto
  2 #include<bits/stdc++.h>
  3 #define inf 0x3f3f3f3f
  4 using namespace std;
  5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
  6 char buf[1<<21],*p1=buf,*p2=buf;
  7 inline int read(){
  8     #define num ch-'0'
  9     char ch;bool flag=0;int res;
 10     while(!isdigit(ch=getc()))
 11     (ch=='-')&&(flag=true);
 12     for(res=num;isdigit(ch=getc());res=res*10+num);
 13     (flag)&&(res=-res);
 14     #undef num
 15     return res;
 16 }
 17 char obuf[1<<24],*o=obuf;
 18 inline void print(int x){
 19     if(x>9) print(x/10);
 20     *o++=x%10+48;
 21 }
 22 const int N=100005;
 23 int ver[N<<1],head[N],Next[N<<1];
 24 int rev[N],fa[N],ch[N][2],w[N],col[N],lmn[N],rmn[N],len[N],val[N];
 25 multiset<int> s[N];
 26 int n,q,white=0,tot;
 27 #define ls ch[x][0]
 28 #define rs ch[x][1]
 29 inline int fir(multiset<int> &s){return s.size()?*s.begin():inf;}
 30 inline int min(int x,int y,int z){return min(x,min(y,z));}
 31 inline bool add(int u,int v){ver[++tot]=v,Next[tot]=head[u],head[u]=tot;}
 32 inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
 33 inline void init(){for(int i=0;i<=n;++i) lmn[i]=rmn[i]=w[i]=inf;}
 34 inline void pushr(int x){
 35     rev[x]^=1,swap(ls,rs),swap(lmn[x],rmn[x]);
 36 }
 37 inline void pushup(int x){
 38     if(!x) return;
 39     len[x]=len[ls]+len[rs]+val[x];
 40     lmn[x]=min(lmn[ls],len[ls]+val[x]+min(w[x],fir(s[x]),lmn[rs]));
 41     rmn[x]=min(rmn[rs],len[rs]+min(w[x],fir(s[x]),rmn[ls]+val[x]));
 42 }
 43 inline void pushdown(int x){
 44     if(x&&rev[x]){
 45         pushr(ls),pushr(rs),rev[x]=0;
 46     }
 47 }
 48 void rotate(int x){
 49     int y=fa[x],z=fa[y],d=ch[y][1]==x;
 50     if(!isroot(y)) ch[z][ch[z][1]==y]=x;
 51     fa[x]=z,fa[y]=x,fa[ch[x][d^1]]=y,ch[y][d]=ch[x][d^1],ch[x][d^1]=y,pushup(y);
 52 }
 53 void down(int x){
 54     if(!isroot(x)) down(fa[x]);
 55     pushdown(x);
 56 }
 57 void splay(int x){
 58     down(x);
 59     for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
 60         if(!isroot(y))
 61         ((ch[z][1]==y)^(ch[y][1]==x))?rotate(x):rotate(y);
 62         rotate(x);
 63     }
 64     pushup(x);
 65 }
 66 void access(int x){
 67     for(int y=0;x;x=fa[y=x]){
 68         splay(x);
 69         if(rs) s[x].insert(lmn[rs]);
 70         if(y) s[x].erase(s[x].find(lmn[y]));
 71         rs=y,pushup(x);
 72     }
 73 }
 74 void modify(int x){
 75     access(x),splay(x);
 76     col[x]^=1,w[x]=col[x]?0:inf;
 77     col[x]?(++white):(--white);
 78     pushup(x);
 79 }
 80 int query(int x){
 81     access(x),splay(x);
 82     return rmn[x];
 83 }
 84 void dfs(int u){
 85     for(int i=head[u];i;i=Next[i]){
 86         int v=ver[i];
 87         if(v==fa[u]) continue;
 88         fa[v]=u,val[v]=1,dfs(v);
 89         s[u].insert(lmn[v]);
 90     }
 91     pushup(u);
 92 }
 93 int main(){
 94     //freopen("testdata.in","r",stdin);
 95     n=read();init();
 96     for(int i=1;i<n;++i){
 97         int u=read(),v=read();
 98         add(u,v),add(v,u);
 99     }
100     dfs(1);q=read();
101     while(q--){
102         int op=read(),x=read();
103         if(op){
104             if(!white) *o++='-',*o++='1';
105             else if(col[x]) *o++='0';
106             else print(query(x));
107             *o++='\n';
108         }
109         
110         else modify(x);
111     }
112     fwrite(obuf,o-obuf,1,stdout);
113     return 0;
114 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9428573.html

相关文章:

  • C/C++ Volatile关键词深度剖析
  • word2vec原理(一) CBOW与Skip-Gram模型基础——转载自刘建平Pinard
  • Treap实现的名次树
  • 最短路径SPFA算法(邻接表存法)
  • python 读取文件基本格式
  • Spring注入静态变量
  • Hadoop的hdfs api操作
  • 反射获取枚举的属性注释
  • 各种卷积结构原理及优劣总结
  • linux 程序管理
  • mysql 索引使用教程
  • C#操作MongoDB
  • 分页器(自定制)
  • [转]Linux下防止进程使用swap及防止OOM机制导致进程被kill掉
  • springMVC集成activiti-explorer5.22(一)
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • HTML-表单
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • HTTP中的ETag在移动客户端的应用
  • ng6--错误信息小结(持续更新)
  • rc-form之最单纯情况
  • XML已死 ?
  • 成为一名优秀的Developer的书单
  • 规范化安全开发 KOA 手脚架
  • 前端技术周刊 2019-02-11 Serverless
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 问题之ssh中Host key verification failed的解决
  • 我建了一个叫Hello World的项目
  • 译米田引理
  • gunicorn工作原理
  • ​​​​​​​​​​​​​​Γ函数
  • #pragma pack(1)
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (转)nsfocus-绿盟科技笔试题目
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @Controller和@RestController的区别?
  • @property python知乎_Python3基础之:property
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [Android Studio] 开发Java 程序
  • [AutoSAR 存储] 汽车智能座舱的存储需求
  • [C#]C# winform部署yolov8目标检测的openvino模型
  • [dfs搜索寻找矩阵中最长递减序列]魔法森林的秘密路径