题解 CF165D 【Beard Graph】
思路:将黑边标记为1,白边标记为100000,树链剖分
如果查询时ans超过100000,那就有白边,输出-1,不然直接输出ans
#include<bits/stdc++.h>
#define maxn 800001
#define int long long
#define L(x) (x<<1)
#define R(x) ((x<<1)|1)
using namespace std;
int tree[maxn],tag[maxn];
int rev[maxn],dep[maxn],size[maxn],seg[maxn],top[maxn],son[maxn],father[maxn];
int n,m,root,x,y,z,a[maxn],tot,mode;
int cnt,from[maxn],to[maxn],Next[maxn],head[maxn];
int Gx,Gy,Gz,Gd;
int fa[maxn],X[maxn],Y[maxn],Z[maxn];
void add(int x,int y){
cnt++;
from[cnt]=x;to[cnt]=y;
Next[cnt]=head[x];head[x]=cnt;
}
void update(int node,int begin,int end,int x,int y,int val){
if(begin>y||end<x)return;
if(begin>=x&&end<=y){
tree[node]=val;
return;
}else{
int mid=(begin+end)>>1;
if(x<=mid)update(L(node),begin,mid,x,y,val);
if(y>mid) update(R(node),mid+1,end,x,y,val);
tree[node]=tree[L(node)]+tree[R(node)];
}
}
int query(int node,int begin,int end,int x,int y){
if(begin>=x&&end<=y){
return tree[node];
}else{
int mid=(begin+end)>>1,sum=0;
if(x<=mid)sum+=query(L(node),begin,mid,x,y);
if(y>mid) sum+=query(R(node),mid+1,end,x,y);
return sum;
}
}
int dfs1(int x){
size[x]=1;
dep[x]=dep[father[x]]+1;
for(int i=head[x];i!=-1;i=Next[i]){
int v=to[i],big=0;
if(father[x]==v)continue;
father[v]=x;
big=dfs1(v);
size[x]+=big;
if(big>size[son[x]])son[x]=v;
}
return size[x];
}
void dfs2(int x){
if(son[x]){
seg[son[x]]=++seg[0];
top[son[x]]=top[x];
rev[seg[0]]=son[x];
dfs2(son[x]);
}
for(int i=head[x];i!=-1;i=Next[i]){
int v=to[i];
if(!top[v]){
seg[v]=++seg[0];
top[v]=v;
rev[seg[0]]=v;
dfs2(v);
}
}
}
int linkquery(int x,int y){
int fx=top[x],fy=top[y],ans=0;
while(fx!=fy){
if(dep[fx]<dep[fy])swap(x,y),swap(fx,fy);
ans+=query(1,1,seg[0],seg[fx],seg[x]);
x=father[fx];fx=top[x];
}
if(dep[x]>dep[y])swap(x,y);
ans+=query(1,1,seg[0],seg[x],seg[y]);
ans-=query(1,1,seg[0],seg[x],seg[x]);
return ans;
}
void change(int x,int y){
x*=2;
x=dep[from[x]]>dep[to[x]]?from[x]:to[x];
update(1,1,seg[0],seg[x],seg[x],y);
}
signed main(){
memset(head,-1,sizeof(head));
scanf("%lld",&n);root=1;
for(int i=1;i<=n-1;i++){
scanf("%lld%lld",&x,&y);
add(x,y),add(y,x);
}
dfs1(root);
seg[root]=++seg[0];
rev[seg[0]]=root;
top[root]=root;
dfs2(root);
scanf("%lld",&m);
for(int i=1;i<=n-1;i++)change(i,1);
for(int i=1;i<=m;i++){
scanf("%lld%lld",&mode,&x);
if(mode==1)change(x,1);
if(mode==2)change(x,100000);
if(mode==3){
scanf("%lld",&y);
int ans=0;
ans=linkquery(x,y);
if(ans>=100000)printf("-1\n");else
printf("%lld\n",ans);
}
}
}
题解 CF165D 【Beard Graph】的更多相关文章
- CF165D Beard Graph
$ \color{#0066ff}{ 题目描述 }$ 给定一棵树,有m次操作. 1 x 把第x条边染成黑色 2 x 把第x条边染成白色 3 x y 查询x~y之间的黑边数,存在白边输出-1 \(\co ...
- CF165D Beard Graph(dfs序+树状数组)
题面 题解 乍一看,单点修改,单链查询,用树链剖分维护每条链上白边的数量就完了, 还是--得写树链剖分吗?--3e5,乘两个log会T吗-- (双手颤抖) (纠结) 不!绝不写树链剖分! 这题如果能维 ...
- 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 ...
- 树链剖分【CF165D】Beard Graph
Description 给定一棵树,有m次操作. 1 x 把第x条边染成黑色 2 x 把第x条边染成白色 3 x y 查询x~y之间的黑边数,存在白边输出-1 Input 第1行为一个整数\(n\), ...
- 【题解】G.Graph(2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest)
题目链接G题 题意 序列 \(a_1,a_2,⋯,a_n\) 是一个排列, 当且仅当它含有 1 到 n 的所有整数. 排列 \(a_1,a_2,⋯,a_n\) 是一个有向图的拓扑排序,当且仅当对于每条 ...
- codeforces 165D.Beard Graph 解题报告
题意: 给一棵树,树的每条边有一种颜色,黑色或白色,一开始所有边均为黑色,有两个操作: 操作1:将第i条边变成白色或将第i条边变成黑色. 操作2 :询问u,v两点之间仅经过黑色变的最短距离. 树链剖分 ...
- LeetCode题解之Clone Graph
1.题目描述 2.问题分析 要遍历图,然后标记没有被复制的节点. 3.代码 class Solution { private: unordered_map<Node*, Node*> m; ...
- 题解 UVA1479 【Graph and Queries】
\[ \text{Preface} \] 算是一道思维难度稍易,代码难度稍难的题吧. \[ \text{Description} \] 给出一张 \(n\) 个点,\(m\) 条边的图,点带权.需要支 ...
- 算法与数据结构基础 - 图(Graph)
图基础 图(Graph)应用广泛,程序中可用邻接表和邻接矩阵表示图.依据不同维度,图可以分为有向图/无向图.有权图/无权图.连通图/非连通图.循环图/非循环图,有向图中的顶点具有入度/出度的概念. 面 ...
随机推荐
- iOS 开发之基于JWT的Token认证机制及解析
在移动端和服务端通信中,一般有两种认证方式:token 和 session. 1.session/cookie 认证机制: 在服务端创建一个Session对象,同时在客户端的浏览器端创建一个Cooki ...
- MQTT 入门介绍
一.简述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级& ...
- dapper基本操作
https://www.cnblogs.com/vichin/p/9289969.html
- Centos5.5+LAMP环境
Note:如果网络正常,apache服务正常,仍然不能访问网页.需要检查linux 防火墙是否关闭. ( 先重新启动防火墙 service iptables start 然后输入配置防火墙的命令并查看 ...
- P2774 方格取数(网络流)
https://www.luogu.com.cn/problem/P2774 在一个有 m×n 个方格的棋盘中,每个方格中有一个正整数. 现要从方格中取数,使任意2个数所在方格没有公共边,且取出的数的 ...
- replace() 方法用在字符串中用一些字符替换另一些字符实例
后台给返回的格式是这样的 控制台打印出来格式是这样的 现在需要将这个字符串的数据显示在界面上,1-网站:2-APP:3-客户端 for(var i = 0; i < list.length; i ...
- Thread线程
1.什么是线程? 线程( Thread ) 被称作轻量级进程( Lightweight Process ),线程是比进程更小一级的执行单元. 一个进程可以有多个线程,但至少有一个线程(当进程被初始化后 ...
- VSCODE 教程网
http://geek-docs.com/vscode/vscode-tutorials/vs-code-text-selection.html
- Python基础入门语法1
PY的交换值的方法 x.y = y.x PY既具有动态脚本的特性,又有面向对象的特性 PY的缺点: 编译型的语言(C++,C):通过编译器进行编译成机器码,越接近底层,开发效率低 解释型代码:PY和J ...
- 【协作式原创】查漏补缺之乐观锁与悲观锁TODO
面试官:你了解乐观锁和悲观锁吗? 乐观锁和悲观锁是两种思想,用于解决并发场景下的数据竞争问题. 悲观锁的实现方式是加锁,加锁既可以是对代码块加锁(如Java的synchronized关键字),也可以是 ...