SPOJ QTREE6 lct
岛娘出的题。还是比較easy的
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <time.h>
- #include <vector>
- #include <map>
- #include <queue>
- #include <algorithm>
- #include <stack>
- #include <cstring>
- #include <cmath>
- #include <set>
- #include <vector>
- using namespace std;
- template <class T>
- inline bool rd(T &ret) {
- char c; int sgn;
- if (c = getchar(), c == EOF) return 0;
- while (c != '-' && (c<'0' || c>'9')) c = getchar();
- sgn = (c == '-') ?
- -1 : 1;
- ret = (c == '-') ?
- 0 : (c - '0');
- while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
- ret *= sgn;
- return 1;
- }
- template <class T>
- inline void pt(T x) {
- if (x <0) {
- putchar('-');
- x = -x;
- }
- if (x>9) pt(x / 10);
- putchar(x % 10 + '0');
- }
- typedef long long ll;
- typedef pair<int, int> pii;
- const int N = 100005;
- const int inf = 10000000;
- struct Node *null;
- struct Node {
- Node *fa, *ch[2];
- int id;
- int s[2];//s[0] this虚边所连的全部子树的连续白色点数总和(不是链)
- int col;
- int ls[2], rs[2], siz;
- //ls[0]是对于这条链 最上端向下的连续白色点数
- int Ls[2], Rs[2];
- //Ls[0]是对于这棵子树 与最上端点相连的连续白色点数
- bool rev;
- inline void clear(int _col, int _id) {
- fa = ch[0] = ch[1] = null;
- siz = 1;
- rev = 0;
- id = _id;
- col = _col;
- for (int i = 0; i < 2; i++) {
- ls[i] = rs[i] = s[i] = 0;
- }
- }
- inline void push_up() {
- if (this == null)return;
- siz = ch[0]->siz + ch[1]->siz + 1;
- for (int i = 0; i < 2; i++) {
- ls[i] = ch[0]->ls[i], rs[i] = ch[1]->rs[i];
- Ls[i] = ch[0]->Ls[i], Rs[i] = ch[1]->Rs[i];
- if (ch[0]->ls[i] == ch[0]->siz && i == col) {
- ls[i] = ch[0]->siz + 1 + ch[1]->ls[i];
- Ls[i]++;
- Ls[i] += s[i];
- Ls[i] += ch[1]->Ls[i];
- }
- if (ch[1]->rs[i] == ch[1]->siz && i == col) {
- rs[i] = ch[1]->siz + 1 + ch[0]->rs[i];
- Rs[i]++;
- Rs[i] += s[i];
- Rs[i] += ch[0]->Rs[i];
- }
- }
- }
- inline void push_down() {
- if (rev) {
- ch[0]->flip();
- ch[1]->flip();
- rev = 0;
- }
- }
- inline void setc(Node *p, int d) {
- ch[d] = p;
- p->fa = this;
- }
- inline bool d() {
- return fa->ch[1] == this;
- }
- inline bool isroot() {
- return fa == null || fa->ch[0] != this && fa->ch[1] != this;
- }
- inline void flip() {
- if (this == null)return;
- swap(ch[0], ch[1]);
- rev ^= 1;
- }
- inline void go() {//从链头開始更新到this
- if (!isroot())fa->go();
- push_down();
- }
- inline void rot() {
- Node *f = fa, *ff = fa->fa;
- int c = d(), cc = fa->d();
- f->setc(ch[!c], c);
- this->setc(f, !c);
- if (ff->ch[cc] == f)ff->setc(this, cc);
- else this->fa = ff;
- f->push_up();
- }
- inline Node*splay() {
- go();
- while (!isroot()) {
- if (!fa->isroot())
- d() == fa->d() ? fa->rot() : rot();
- rot();
- }
- push_up();
- return this;
- }
- inline Node* access() {//access后this就是到根的一条splay。而且this已经是这个splay的根了
- for (Node *p = this, *q = null; p != null; q = p, p = p->fa) {
- p->splay();
- if (p->ch[1] != null)
- for (int i = 0;i < 2;i++)
- p->s[i] += p->ch[1]->Ls[i];
- if (q != null)
- for (int i = 0; i < 2; i++)
- p->s[i] -= q->Ls[i];
- p->setc(q, 1);
- p->push_up();
- }
- return splay();
- }
- inline Node* find_root() {
- Node *x;
- for (x = access(); x->push_down(), x->ch[0] != null; x = x->ch[0]);
- return x;
- }
- void make_root() {
- access()->flip();
- }
- void cut() {//把这个点的子树脱离出去
- access();
- ch[0]->fa = null;
- ch[0] = null;
- push_up();
- }
- void cut(Node *x) {
- if (this == x || find_root() != x->find_root())return;
- else {
- x->make_root();
- cut();
- }
- }
- void link(Node *x) {
- if (find_root() == x->find_root())return;
- else {
- make_root(); fa = x;
- }
- }
- };
- Node pool[N], *tail;
- Node *node[N];
- int n, q;
- struct Edge {
- int to, nex;
- }edge[N << 1];
- int head[N], edgenum;
- void add(int u, int v) {
- Edge E = { v, head[u] };
- edge[edgenum] = E;
- head[u] = edgenum++;
- }
- void dfs(int u, int fa) {
- for (int i = head[u]; ~i; i = edge[i].nex) {
- int v = edge[i].to; if (v == fa)continue;
- node[v]->fa = node[u];
- dfs(v, u);
- for (int j = 0; j < 2; j++)
- node[u]->s[j] += node[v]->Ls[j];
- }
- node[u]->push_up();
- }
- int main() {
- while (cin >> n) {
- memset(head, -1, sizeof head); edgenum = 0;
- for (int i = 1, u, v; i < n; i++) {
- rd(u); rd(v);
- add(u, v);add(v, u);
- }
- tail = pool;
- null = tail++;
- null->clear(-1, 0); null->siz = 0;
- for (int i = 1; i <= n; i++)
- {
- node[i] = tail++;
- node[i]->clear(1, i);
- }
- dfs(1, 1);
- rd(q); int u, v;
- while (q--) {
- rd(u); rd(v);
- if (!u) {
- node[v]->access();
- pt(max(node[v]->Rs[0], node[v]->Rs[1])); puts("");
- }
- else {
- node[v]->access();
- node[v]->col ^= 1;
- node[v]->push_up();
- }
- }
- }
- return 0;
- }
SPOJ QTREE6 lct的更多相关文章
- SPOJ - OTOCI LCT
OTOCI Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/problem/viewProblem. ...
- SPOJ QTREE4 lct
题目链接 这个题已经处于花式tle了,改版后的spoj更慢了.. tle的话就多交几把... #include <iostream> #include <fstream> #i ...
- SPOJ QTREE6
题意 给你一棵\(n\)个点的树,编号\(1\)~\(n\).每个点可以是黑色,可以是白色.初始时所有点都是黑色.有两种操作 \(0\ u\):询问有多少个节点\(v\)满足路径\(u\)到\(v\) ...
- SPOJ QTREE3 lct
题目链接 题意: 给定n个点 q个询问 以下n-1行给出树边,点有黑或白色.初始化为白色 以下q行: 询问有2种: 1. 0 x 把x点黑变白,白变黑 2.1 x 询问Path(1,x)路径上第一个黑 ...
- SPOJ QTREE2 lct
题目链接 题意: 给一棵树.有边权 1.询问路径的边权和 2.询问沿着路径的第k个点标. 思路:lct裸题. #include <iostream> #include <fstrea ...
- SPOJ QTREE5 lct
题目链接 对于每一个节点,记录这个节点所在链的信息: ls:(链的上端点)距离链内部近期的白点距离 rs:(链的下端点)距离链内部近期的白点距离 注意以上都是实边 虚边的信息用一个set维护. set ...
- SPOJ QTREE6 Query on a tree VI 树链剖分
题意: 给出一棵含有\(n(1 \leq n \leq 10^5)\)个节点的树,每个顶点只有两种颜色:黑色和白色. 一开始所有的点都是黑色,下面有两种共\(m(1 \leq n \leq 10^5) ...
- bzoj3637 CodeChef SPOJ - QTREE6 Query on a tree VI 题解
题意: 一棵n个节点的树,节点有黑白两种颜色,初始均为白色.两种操作:1.更改一个节点的颜色;2.询问一个节点所处的颜色相同的联通块的大小. 思路: 1.每个节点记录仅考虑其子树时,假设其为黑色时所处 ...
- 【SPOJ】QTREE6(Link-Cut-Tree)
[SPOJ]QTREE6(Link-Cut-Tree) 题面 Vjudge 题解 很神奇的一道题目 我们发现点有黑白两种,又是动态加边/删边 不难想到\(LCT\) 最爆力的做法,显然是每次修改单点颜 ...
随机推荐
- vue计算属性computed和methods的区别
computed和methods的区别 在new Vue的配置参数中的computed和methods都可以处理大量的逻辑代码,但是什么时候用哪个属性,要好好区分一下才能做到正确的运用vue. com ...
- 小程序之如何设置图片以及image组件的属性
1. 设置图片,小程序支持两种引用图片方法,一种是本地引用,一种是网络资源引用. 但是引用本地图片的的时候不能用wxml样式去引用本地的图片,不会报错,也没效果.就是在wxss页面中不能引用本地的图片 ...
- sql语句执行顺序与性能优化(1)
一.首先我们看一下mysql的sql语句的书写顺序 . select--distinct--from--on--where--group by--having--聚合函数cube.rollup--or ...
- Linux启动流程CentOS6和7的区别
目 录 Linux启动流程 I 第1章 CentOS6启动流程 1 1.1 BIOS 1 1.2 MBR 1 1.3 GRUB 1 1.4 kernel(加载内核) ...
- CSS3---关于背景
1.background-origin:设置元素背景图片的原始起始位置. background-origin : border-box | padding-box | content-box; ...
- Elastic-Job-Lite 源码分析 —— 作业分片策略
摘要: 原创出处 http://www.iocoder.cn/Elastic-Job/job-sharding-strategy/ 「芋道源码」欢迎转载,保留摘要,谢谢! 本文基于 Elastic-J ...
- luogu3157 [CQOI2011]动态逆序对
先算出一个点前头比它大和后头比它小的数量. 每次删点就扔进一个主席树里头,防止造成重复删答案. #include <iostream> #include <cstring> # ...
- OO第二次作业
第一次作业: 由于第一次作业的调度较为简单,采用FIFO策略,以及不支持捎带功能,因此我的第一次电梯作业并没有设置单独的调度器,而会直接将任务交给电梯,电梯进行调度策略也仅为先运动到people的In ...
- [luoguP1186] 玛丽卡(spfa)
传送门 因为要随机删除一条边,而枚举所有边肯定会超时,经过发现,先求出一遍最短路,而要删除的边肯定在最短路径上,删除其他的边对最短路没有影响. 所以可以先求出最短路,再枚举删除最短路上的每一条边再求最 ...
- [HDU3062]Party(2-sat)
传送门 2-sat问题,只需要判断yes或no 所以可以直接连边,缩点,判断同一组的是否在同一个块中. #include <cstdio> #include <stack> # ...