【BZOJ2631】tree (LCT)

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2631

终于学了LCT惹qwq (看的板是黄学长的orzzz

T了很久发现窝开了个ch[MaxN][0] ,这都能编译过?

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <iostream>
  4 #include <algorithm>
  5 #define mod 51061
  6 #define MaxN 100010
  7 using namespace std;
  8 int n, q;
  9 int ch[MaxN][2];
 10 unsigned int sum[MaxN], sz[MaxN], ad[MaxN], mu[MaxN], Q[MaxN], p[MaxN], flip[MaxN], val[MaxN];
 11
 12 void updata(int x, int m, int a){
 13     val[x] = (val[x]*m + a) % mod;
 14     sum[x] = (sum[x]*m + a*sz[x]) % mod;
 15     ad[x] = (ad[x] * m + a) % mod;
 16     mu[x] = (mu[x] * m) % mod;
 17 }
 18
 19 void push_up(int x){
 20     int l = ch[x][0], r = ch[x][1];
 21     sz[x] = (sz[l]+sz[r]+1) % mod;
 22     sum[x] = (sum[l]+sum[r]+val[x]) % mod;
 23 }
 24
 25 void push_down(int x){
 26     int l = ch[x][0], r = ch[x][1];
 27         if (flip[x]) {
 28         flip[x] = 0; flip[l] ^= 1; flip[r] ^= 1;
 29         swap(ch[x][0], ch[x][1]);
 30     }
 31     int m = mu[x], a = ad[x];
 32     if (m != 1 || a != 0) {
 33         updata(l, m, a);
 34         updata(r, m, a);
 35         mu[x] = 1, ad[x] = 0;
 36     }
 37 }
 38
 39 bool isroot(int x){
 40     return ch[p[x]][0] != x && ch[p[x]][1] != x;
 41 }
 42
 43 void rotate(int x){
 44     int y = p[x], z = p[y];
 45     if (!isroot(y)) ch[z][ch[z][1] == y] = x;
 46     int l = ch[y][1] == x, r = l ^ 1;
 47     p[y] = x;
 48     p[x] = z;
 49     p[ch[x][r]] = y;
 50
 51     ch[y][l] = ch[x][r];
 52     ch[x][r] = y;
 53     push_up(y);
 54     push_up(x);
 55 }
 56
 57 void splay(int x){
 58     int top = 1;
 59     Q[top] = x;
 60     for (int t = x; !isroot(t); t = p[t]) Q[++top] = p[t];
 61     while (top) push_down(Q[top--]);
 62     while (!isroot(x)){
 63         int y = p[x], z = p[y];
 64         if (!isroot(y)){
 65             if ((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(x);
 66             else rotate(y);
 67         }
 68         rotate(x);
 69     }
 70 }
 71
 72 void Access(int x){
 73     for (int t = 0; x; t = x, x = p[x]){
 74         splay(x); ch[x][1] = t; push_up(x);
 75     }
 76 }
 77
 78 void Make_root(int x){
 79     Access(x); splay(x); flip[x] ^= 1;
 80 }
 81
 82 void Link(int u, int v){
 83     Make_root(u); p[u] = v;
 84 }
 85
 86 void Cut(int u, int v){
 87     Make_root(u); Access(v); splay(v);
 88     p[u] = ch[v][0] = 0;
 89 }
 90
 91 void Split(int u, int v){
 92     Make_root(v); Access(u); splay(u);
 93 }
 94
 95 void Read_Data(){
 96     scanf("%d%d", &n, &q);
 97     for (int i = 1; i <= n; i++)
 98         sum[i] = sz[i] = mu[i] = val[i] = 1;
 99     for (int i = 1, u, v; i < n; i++){
100         scanf("%d%d", &u, &v);
101         Link(u, v);
102     }
103 }
104
105 void Solve(){
106     char s[5];
107     int u, v, c, u2, v2;
108     for (int i = 1; i <= q; i++){
109         scanf("%s%d%d", s, &u, &v);
110         if (s[0] == ‘+‘) {
111             scanf("%d", &c);
112             Split(u, v); updata(u, 1, c);
113         }
114         if (s[0] == ‘-‘) {
115             scanf("%d%d", &u2, &v2);
116             Cut(u, v); Link(u2, v2);
117         }
118         if (s[0] == ‘*‘) {
119             scanf("%d", &c);
120             Split(u, v); updata(u, c, 0);
121         }
122         if (s[0] == ‘/‘) {
123             Split(u, v);
124             printf("%d\n", sum[u]);
125         }
126     }
127 }
128
129 int main(){
130     freopen("bzoj2631.in", "r", stdin);
131     freopen("bzoj2631.out", "w", stdout);
132     Read_Data();
133     Solve();
134     return 0;
135 }

_(:з」∠)_

时间: 2024-10-28 20:09:21

【BZOJ2631】tree (LCT)的相关文章

【BZOJ2243】【SDOI2011】染色 (LCT)

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 练了一发LCT,唔调了好久感觉是下传标记的问题可是不知道哪里错了.问了问老司机ljy,确实是出事了.. 唔大概就是 每一次flip的下传要注意一下两个儿子各自的lc和rc吧qwq 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <iostream> 5

【Luogu1501】Tree(Link-Cut Tree)

[Luogu1501]Tree(Link-Cut Tree) 题面 洛谷 题解 \(LCT\)版子题 看到了顺手敲一下而已 注意一下,别乘爆了 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map>

【LeetCode-面试算法经典-Java实现】【110-Balanced Binary Tree(平衡二叉树)】

[110-Balanced Binary Tree(平衡二叉树)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of eve

【SPOJ】QTREE6(Link-Cut-Tree)

[SPOJ]QTREE6(Link-Cut-Tree) 题面 Vjudge 题解 很神奇的一道题目 我们发现点有黑白两种,又是动态加边/删边 不难想到\(LCT\) 最爆力的做法,显然是每次修改单点颜色的时候 暴力修改当前点和它的父亲以及儿子之间的连边状态 但是这样显然是假的(菊花树了解一下) 怎么优化呢? 对于每次操作,我们考虑如何只修改一次. 对于树上的一个结点,如果只修改一次,显然是修改和其父亲的状态. 那么,我们在考虑\(LCT\)的连边操作的时候, 如果当前点变色,那么就只修改和它父亲

【2014】字符串(3)

题目描述(50分): 通过键盘输入100以内正整数的加.减运算式,请编写一个程序输出运算结果字符串. 输入字符串的格式为:"操作数1 运算符 操作数2","操作数"与"运算符"之间以一个空格隔开. 补充说明: 1.操作数为正整数,不需要考虑计算结果溢出的情况. 2.若输入算式格式错误,输出结果为"0". 要求实现函数: void arithmetic(const char *pInputStr, long lInputLen,

【Spring】的【Bean】管理(注解)【四个相同功能的注解】

[Spring]的[Bean]管理(注解)[四个相同功能的注解] 注解:代码里面特殊的标记,使用注解也可以完成一些相关的功能. 注解写法:@注解名称(属性名称=属性值) 注解使用在类.方法.属性上面 (注解可以替代配置文件,并非完全替代): 1.创建类,创建方法 1 public class User { 2 public void add(){ 3 System.out.println("add-----------"); 4 } 5 } 2.创建spring配置文件,引入约束 1

【leetcode】Candy(python)

题目要求比其高的邻居要比本身的奖励多,那么最少也要多一个,所有我们可以找到所有的凹点,凹点如下三种情形. 找到所有的凹点后,我们就可以从凹点处开始向左右两个方向依次查找递增序列,其中每个高的都要比相邻的矮的多一个,比如1,2,5,4.我们找到凹点为1 和4,那么从1开始向左没有其他点,我们向右,依次得到2 比1高,2的糖果应该是1的基础上加1,为2, 5比2高,5的糖果是在2的基础上加1,为3.令一个凹点4, 向左,5比4高,5的糖果应该是在4的基础上加 1,为2,这时我们发现冲突了,从凹点1

【2014】 字符串(2)

题目描述(40分): 通过键盘输入一串小写字母(a~z)组成的字符串.请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串. 压缩规则: 1.仅压缩连续重复出现的字符.比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc". 2.压缩字段的格式为"字符重复的次数+字符".例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz". 要求实现函数: v

【2014】字符串(1)

一.题目描述(60分): 通过键盘输入一串小写字母(a~z)组成的字符串.请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉. 比如字符串"abacacde"过滤结果为"abcde". 要求实现函数:void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr); [输入] pInputStr:  输入字符串 lInputLen:  输入字符串长度 [