$ \color{#0066ff}{ 题目描述 }$

给定一棵树,有m次操作。

1 x 把第x条边染成黑色

2 x 把第x条边染成白色

3 x y 查询x~y之间的黑边数,存在白边输出-1

\(\color{#0066ff}{输入格式}\)

第一行一个正整数N (1 ≤ N ≤ 100000),节点总数

接下来N − 1行,每行两个整数a,b 表示一条边

接下来是一个正整数m(1 ≤ m ≤ 300000),表示共有m次操作。

后面跟着m行,是操作

\(\color{#0066ff}{输出格式}\)

对于每一个询问,输出一行答案

\(\color{#0066ff}{输入样例}\)

3
1 2
2 3
7
3 1 2
3 1 3
3 2 3
2 2
3 1 2
3 1 3
3 2 3 6
1 5
6 4
2 3
3 5
5 6
6
3 3 4
2 5
3 2 6
3 1 2
2 3
3 3 1

\(\color{#0066ff}{输出样例}\)

1
2
1
1
-1
-1 3
-1
3
2

\(\color{#0066ff}{数据范围与提示}\)

none

\(\color{#0066ff}{题解}\)

只有两种颜色,维护两个LCT就行了

LCT上维护siz,询问时siz-1就是答案

无解就是不联通qwq

#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 1e5 + 10;
struct LCT {
protected:
struct node {
node *ch[2], *fa;
int siz, rev;
node(int siz = 0, int rev = 0): siz(siz), rev(rev) {
fa = ch[0] = ch[1] = NULL;
}
void trn() { std::swap(ch[0], ch[1]), rev ^= 1; }
void dwn() {
if(!rev) return;
if(ch[0]) ch[0]->trn();
if(ch[1]) ch[1]->trn();
rev = 0;
}
void upd() { siz = (ch[0]? ch[0]->siz : 0) + (ch[1]? ch[1]->siz : 0) + 1; }
bool isr() { return fa->ch[1] == this; }
bool ntr() { return fa && (fa->ch[1] == this || fa->ch[0] == this); }
}pool[maxn];
void rot(node *x) {
node *y = x->fa, *z = y->fa;
bool k = x->isr(); node *w = x->ch[!k];
if(y->ntr()) z->ch[y->isr()] = x;
(x->ch[!k] = y)->ch[k] = w;
(y->fa = x)->fa = z;
if(w) w->fa = y;
y->upd(), x->upd();
}
void splay(node *o) {
static node *st[maxn];
int top;
st[top = 1] = o;
while(st[top]->ntr()) st[top + 1] = st[top]->fa, top++;
while(top) st[top--]->dwn();
while(o->ntr()) {
if(o->fa->ntr()) rot(o->isr() ^ o->fa->isr()? o : o->fa);
rot(o);
}
}
void access(node *x) {
for(node *y = NULL; x; x = (y = x)->fa)
splay(x), x->ch[1] = y, x->upd();
}
void makeroot(node *x) { access(x), splay(x), x->trn(); }
node *findroot(node *x) {
access(x), splay(x);
while(x->dwn(), x->ch[0]) x = x->ch[0];
return x;
}
public:
void link(int l, int r) {
node *x = pool + l, *y = pool + r;
makeroot(x), x->fa = y;
}
void cut(int l, int r) {
node *x = pool + l, *y = pool + r;
makeroot(x), access(y), splay(y);
if(y->ch[0] == x) y->ch[0] = x->fa = NULL;
}
int query(int l, int r) {
node *x = pool + l, *y = pool + r;
if(findroot(x) != findroot(y)) return -1;
makeroot(x), access(y), splay(y);
return y->siz - 1;
}
}s[2];
std::pair<int, int> mp[maxn];
int col[maxn];
int main() {
int n = in();
for(int i = 1; i < n; i++) s[1].link(mp[i].first = in(), mp[i].second = in()), col[i] = 1;
int x, y, p;
for(int T = in(); T --> 0;) {
p = in();
if(p == 1) {
if(col[x = in()]) continue;
s[0].cut(mp[x].first, mp[x].second);
s[col[x] = 1].link(mp[x].first, mp[x].second);
}
if(p == 2) {
if(!col[x = in()]) continue;
s[1].cut(mp[x].first, mp[x].second);
s[col[x] = 0].link(mp[x].first, mp[x].second);
}
if(p == 3) x = in(), y = in(), printf("%d\n", s[1].query(x, y));
}
return 0;
}

CF165D Beard Graph的更多相关文章

  1. CF165D Beard Graph(dfs序+树状数组)

    题面 题解 乍一看,单点修改,单链查询,用树链剖分维护每条链上白边的数量就完了, 还是--得写树链剖分吗?--3e5,乘两个log会T吗-- (双手颤抖) (纠结) 不!绝不写树链剖分! 这题如果能维 ...

  2. Codeforces Round #112 (Div. 2) D. Beard Graph

    地址:http://codeforces.com/problemset/problem/165/D 题目: D. Beard Graph time limit per test 4 seconds m ...

  3. 树链剖分【CF165D】Beard Graph

    Description 给定一棵树,有m次操作. 1 x 把第x条边染成黑色 2 x 把第x条边染成白色 3 x y 查询x~y之间的黑边数,存在白边输出-1 Input 第1行为一个整数\(n\), ...

  4. 题解 CF165D 【Beard Graph】

    思路:将黑边标记为1,白边标记为100000,树链剖分 如果查询时ans超过100000,那就有白边,输出-1,不然直接输出ans #include<bits/stdc++.h> #def ...

  5. codeforces 165D.Beard Graph 解题报告

    题意: 给一棵树,树的每条边有一种颜色,黑色或白色,一开始所有边均为黑色,有两个操作: 操作1:将第i条边变成白色或将第i条边变成黑色. 操作2 :询问u,v两点之间仅经过黑色变的最短距离. 树链剖分 ...

  6. Codeforces Round #112 (Div. 2)

    Codeforces Round #112 (Div. 2) C. Another Problem on Strings 题意 给一个01字符串,求包含\(k\)个1的子串个数. 思路 统计字符1的位 ...

  7. [开发笔记] Graph Databases on developing

    TimeWall is a graph databases github It be used to apply mathematic model and social network with gr ...

  8. Introduction to graph theory 图论/脑网络基础

    Source: Connected Brain Figure above: Bullmore E, Sporns O. Complex brain networks: graph theoretica ...

  9. POJ 2125 Destroying the Graph 二分图最小点权覆盖

    Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8198   Accepted: 2 ...

随机推荐

  1. angularJS学习(三)——搭建学习环境

    1.安装Node.js 和Testacular 1.1. 安装Node.js及配置部分,在另一篇博文:node.js的安装里面讲到了,地址是:http://www.cnblogs.com/tianxu ...

  2. 【Android】Android 4.0 无法接收开机广播的问题

    [Android]Android 4.0 无法接收开机广播的问题   前面的文章 Android 开机广播的使用 中 已经提到Android的开机启动,但是在Android 4.0 有时可以接收到开机 ...

  3. 2-3 JAVA内存模型

  4. 643. Maximum Average Subarray I 最大子数组的平均值

    [抄题]: Given an array consisting of n integers, find the contiguous subarray of given length k that h ...

  5. convertTo

    转自 http://blog.csdn.net/xiaxiazls/article/details/51204265 在使用Opencv中,常常会出现读取一个图片内容后要把图片内容的像素信息转为浮点并 ...

  6. hdu 4768 Flyer (异或操作的应用)

    2013年长春网络赛1010题 继巴斯博弈(30分钟)签到后,有一道必过题(一眼即有思路). 思路老早就有(40分钟):倒是直到3小时后才被A掉.期间各种换代码姿态! 共享思路: unlucky st ...

  7. [GO]随机数的使用

    package main import ( "math/rand" "time" "fmt" ) func main() { //设置种子, ...

  8. is/as操作符

    is/as操作符,是C#中用于类型转换的,提供了对类型兼容性的判断,从而使得类型转换控制在安全的范畴,提供了灵活的类型转换控制. is规则:检查对象的兼容性,查看对象的类型是否完全一样,返回值 tru ...

  9. 组合(Composite)模式 *

    组合(Composite)模式:将对象组合树形结构以表示‘部分-整体’的层次结构. 组合模式使得用户对单个对象和组合对象具有一致性 /* * 抽象构件(Component)角色:这是一个抽象角色,它给 ...

  10. lda:变分的推导

    lda,latent diriclet allocation,是一个最基本的bayesian模型.本文要研究lda基于变分的推导方法.意义是重大的. 一.符号的定义 : the number of t ...