题解

可以发现每次修改的是这个点往上一条连续的链,如果我要把1改成0,需要满足这一段往上的一部分都有两个1
如果我要把0改成1,需要满足这一段往上的部分有两个0
对于每个点记录1的个数,发现我们只会把一棵树的2全部改成1或者把1全部改成2,这样加标记的时候可以同时维护是否全1或者是否全2,用lct维护,修改的时候access一遍,直接在平衡树上二分即可

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 1000005
#define eps 1e-10
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 + c - '0';c = getchar();}res *= f;
}
template<class T>
void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10);
}
struct node {int lc,rc,fa,val,lz;bool all[2];
}tr[MAXN];
int num[MAXN * 2],N,Q,fa[MAXN * 2],d[2];
vector<int> son[MAXN];
bool isRoot(int u) {if(!tr[u].fa) return true;return tr[tr[u].fa].lc != u && tr[tr[u].fa].rc != u;
}
bool which(int u) {return tr[tr[u].fa].lc == u;
}void addlz(int u,int v) {tr[u].val += v;tr[u].lz += v;tr[u].all[0] = tr[u].all[1] = 0;if(v == -1) tr[u].all[0] = 1;if(v == 1) tr[u].all[1] = 1;
}
void pushdown(int u) {if(tr[u].lz) {if(tr[u].lc) addlz(tr[u].lc,tr[u].lz);if(tr[u].rc) addlz(tr[u].rc,tr[u].lz);tr[u].lz = 0;}
}
void update(int u) {for(int i = 0 ; i <= 1 ; ++i) {tr[u].all[i] = (tr[u].val == i + 1) & tr[tr[u].lc].all[i] & tr[tr[u].rc].all[i];}
}
void Rotate(int u) {int v = tr[u].fa,w = tr[v].fa;if(!isRoot(v)) {(v == tr[w].lc ? tr[w].lc : tr[w].rc) = u;}int b = (u == tr[v].lc ? tr[u].rc : tr[u].lc);tr[u].fa = w;tr[v].fa = u;if(b) tr[b].fa = v;if(u == tr[v].lc) {tr[u].rc = v;tr[v].lc = b;}else {tr[u].lc = v;tr[v].rc = b;}update(v);
}
void Splay(int u) {static int que[MAXN],tot;tot = 0;int x;for(x = u ; !isRoot(x) ; x = tr[x].fa) {que[++tot] = x;}que[++tot] = x;for(int i = tot ; i >= 1 ; --i) {pushdown(que[i]);}while(!isRoot(u)) {if(!isRoot(tr[u].fa)) {if(which(tr[u].fa) == which(u)) Rotate(tr[u].fa);else Rotate(u);}Rotate(u);}update(u);
}
void Access(int u) {for(int x = 0 ; u ; x = u, u = tr[u].fa) {Splay(u);tr[u].rc = x;update(u);}
}
void dfs(int u) {for(int j = 0 ; j < 3 ; ++j) {if(son[u][j] <= N) {dfs(son[u][j]);tr[u].val += (tr[son[u][j]].val >= 2);tr[son[u][j]].fa = u;}else {tr[u].val += num[son[u][j] - N];fa[son[u][j] - N] = u;}}if(tr[u].val == 1) tr[u].all[0] = 1;if(tr[u].val == 2) tr[u].all[1] = 1;
}
void Init() {read(N);int a;for(int i = 1 ; i <= N ; ++i) {for(int j = 0 ; j < 3 ; ++j) {read(a);son[i].pb(a);}}for(int i = 1 ; i <= 2 * N + 1 ; ++i) read(num[i]);dfs(1);
}
void Solve() {read(Q);int v;d[0] = 1,d[1] = -1;tr[0].all[0] = tr[0].all[1] = 1;while(Q--) {read(v);v -= N;Access(fa[v]);Splay(fa[v]);if(tr[fa[v]].all[num[v]]) {addlz(fa[v],d[num[v]]);}else {int p = fa[v],res;while(1) {res = p;pushdown(p);if(tr[p].rc && !tr[tr[p].rc].all[num[v]]) {p = tr[p].rc;continue;}if(tr[p].val != num[v] + 1) break;if(tr[p].lc && !tr[tr[p].lc].all[num[v]]) {p = tr[p].lc;continue;}break;}Splay(res);if(tr[res].rc) addlz(tr[res].rc,d[num[v]]);tr[res].val += d[num[v]];update(res);}num[v] ^= 1;Splay(1);out(tr[1].val >= 2);enter;}
}
int main() {
#ifdef ivorysifreopen("f1.in","r",stdin);
#endifInit();Solve();
}

转载于:https://www.cnblogs.com/ivorysi/p/10491545.html

【LOJ】#2187. 「SHOI2014」三叉神经树相关推荐

  1. Loj #2983. 「WC2019」数树

    Loj #2983. 「WC2019」数树 题目背景 白兔喜欢树. 白云喜欢数数. 有 \(n\) 只鼠,白兔用 \(n − 1\) 根蓝色绳子把它们连成了一棵树,每根蓝色绳子连着两只鼠,白云用 \( ...

  2. 【LOJ】#2983. 「WC2019」数树

    LOJ2983. 「WC2019」数树 task0 有\(i\)条边一样答案就是\(y^{n - i}\) task1 这里有个避免容斥的方法,如果有\(i\)条边重复我们要算的是\(y^{n - i ...

  3. Loj #3111. 「SDOI2019」染色

    Loj #3111. 「SDOI2019」染色 题目描述 给定 \(2 \times n\) 的格点图.其中一些结点有着已知的颜色,其余的结点还没有被染色.一个合法的染色方案不允许相邻结点有相同的染色 ...

  4. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  5. LOJ#2230. 「BJOI2014」大融合

    LOJ#2230. 「BJOI2014」大融合 题目描述 小强要在$N$个孤立的星球上建立起一套通信系统.这套通信系统就是连接$N$个点的一个树.这个树的边是一条一条添加上去的. 在某个时刻,一条边的 ...

  6. Loj #2568. 「APIO2016」烟花表演

    Loj #2568. 「APIO2016」烟花表演 题目描述 烟花表演是最引人注目的节日活动之一.在表演中,所有的烟花必须同时爆炸.为了确保安全,烟花被安置在远离开关的位置上,通过一些导火索与开关相连 ...

  7. Loj #2554. 「CTSC2018」青蕈领主

    Loj #2554. 「CTSC2018」青蕈领主 题目描述 "也许,我的生命也已经如同风中残烛了吧."小绿如是说. 小绿同学因为微积分这门课,对"连续"这一概 ...

  8. loj#2143. 「SHOI2017」组合数问题

    loj#2143. 「SHOI2017」组合数问题 题目描述 Solution 考虑转化一下我们要求的东西. ∑i=0n(nkik+r)=∑i=0n(nki)[i≡r(modk)]\sum_{i=0} ...

  9. LOJ#2542. 「PKUWC2018」随机游走

    LOJ#2542. 「PKUWC2018」随机游走 题目描述 Solution 去过一个点集中所有节点的期望时间不好求,考虑min−maxmin-maxmin−max容斥,转化为求第一次到达某一个点集 ...

  10. LOJ#2145. 「SHOI2017」分手是祝愿

    LOJ#2145. 「SHOI2017」分手是祝愿 题目描述 Solution 首先有一个结论: 灯的状态序列a1,a2...ana_1,a_2...a_na1​,a2​...an​唯一对应了一个最优 ...

最新文章

  1. CentOS下Docker安装
  2. 在PPT中通过插入重叠的图形获得新的图形
  3. 查询前几条记录SQL在不同数据库中的用法
  4. (仿头条APP项目)4.父类BaseFragment创建,用retrofit和gson获取并解析服务器端数据
  5. 解决 wget 使用 https 下载报错的问题
  6. 自动语音识别(ASR)自监督方法研究综述
  7. PAT (Basic Level) Practice (中文)1003 我要通过! (20 分)
  8. 用于基于SWT的应用程序的RichText编辑器组件
  9. 天天向上续python3.3_Linux 配置系列 四 python3
  10. 基于android的交流平台,基于Android的移动学习交流平台的设计与实现
  11. 华视读卡器多浏览器插件_翻遍Chrome商店,这9款插件值得安装
  12. C++对输入流输出流运算符的重载【案例】
  13. 通过wifi使用nfs把ubuntu挂载到android
  14. 谷歌浏览器不能上网的解决办法之一
  15. python资本市场财务数据分析_不懂财务数据分析?教你一分钟看懂财务报表
  16. html页面整体缩小,浏览器缩放原理以及窗口、html页面大小
  17. ospf在NBMA网络中的配置
  18. 【我的Android进阶之旅】解决魅族手机USB调试时,无法授权出现“Because an app is obscuring a permission request.”错误提示的问题
  19. java类图与代码实例
  20. 代码已开源,一起魔改大西瓜!

热门文章

  1. Mysql和mono_c# – 让Linq与Mysql和Mono玩得很好,有可能吗?
  2. python中argsparse_Python中的argparse模块
  3. 建模算法(五)——图与网络
  4. Docker 入门实践
  5. 虚拟机上网设置教程之如何用虚拟机上网
  6. C#开发微信门户及应用(13)-使用地理位置扩展相关应用
  7. POJ_1753解答过程的理解
  8. 细算经典网游私服新作下刀的“手术”
  9. 【Webcam设计】客户机与程序之间的通信cv::imencode/imdecode与 std::ifstream file与imread/imwrite方式
  10. socket.h中定义的函数