CodeForces - 343D 树链剖分
题目链接:http://codeforces.com/problemset/problem/343/D
题意:给定一棵n个n-1条边的树,起初所有节点权值为0,然后m个操作。 1 x:把x为根的子树的点的权值修改为1; 2 x:把x结点到根路径上的点修改为0; 3 x:查询结点x的值。
思路:树链剖分。 对于操作1,子树操作记录下当前点为根时,dfs的最后一个点的id是多少(endid[]),然后就可以把子树操作用区间来维护了。 对于操作2,树链剖分。 对于3操作,线段树单点查询。
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<time.h>
#include<cmath>
#include<sstream>
#include<assert.h>
using namespace std;
#define L(x) x<<1
#define R(x) x<<1|1
typedef long long int LL;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
const int MAXN = + ;
int head[MAXN], tot, cnt;
struct Edge{
int to, next;
}Edges[MAXN * ];
void add(int u, int v){
Edges[tot].to = v;
Edges[tot].next = head[u];
head[u] = tot++;
}
int id[MAXN], endid[MAXN],son[MAXN], deep[MAXN], size[MAXN], fa[MAXN], reid[MAXN], top[MAXN];
void Init(){
tot = ; cnt = ;
memset(head, -, sizeof(head));
memset(son, -, sizeof(son));
}
void DFS1(int u, int p,int dep){
fa[u] = p; size[u] = ; deep[u] = dep;
for (int i = head[u]; i != -; i = Edges[i].next){
if (Edges[i].to != p){
DFS1(Edges[i].to, u,dep+);
size[u] += size[Edges[i].to];
if (son[u] == - || size[Edges[i].to] > size[son[u]]){
son[u] = Edges[i].to;
}
}
}
}
void DFS2(int u, int tp){
id[u] = ++cnt; reid[id[u]] = u; top[u] = tp;
if (son[u] == -){ endid[u] = cnt; return; }
DFS2(son[u], tp);
for (int i = head[u]; i != -; i = Edges[i].next){
if (son[u] != Edges[i].to&&Edges[i].to != fa[u]){
DFS2(Edges[i].to, Edges[i].to);
}
}
endid[u] = cnt;
}
struct Node{
int st, ed;
int lazy,val;
}Seg[MAXN * ];
void pushDown(int k){
if (Seg[k].lazy!=-){
Seg[L(k)].lazy = Seg[L(k)].val = Seg[k].lazy;
Seg[R(k)].lazy = Seg[R(k)].val = Seg[k].lazy;
Seg[k].lazy = -;
}
}
void Build(int l, int r, int k){
Seg[k].st = l; Seg[k].ed = r; Seg[k].lazy = -; Seg[k].val = ;
if (l == r){
return;
}
int mid = (l + r) / ;
Build(l, mid, L(k)); Build(mid + , r, R(k));
}
void Modify(int l,int r,int val,int k){
if (Seg[k].st == l&&Seg[k].ed == r){
Seg[k].lazy = Seg[k].val = val;
return;
}
pushDown(k);
if (r <= Seg[L(k)].ed){
Modify(l, r, val, L(k));
}
else if (l >= Seg[R(k)].st){
Modify(l, r, val, R(k));
}
else{
Modify(l, Seg[L(k)].ed, val, L(k));
Modify(Seg[R(k)].st, r, val, R(k));
}
}
void Modify(int u, int v,int val){
int f1 = top[u], f2 = top[v];
while (f1 != f2){
if (deep[f1] < deep[f2]){
swap(f1, f2);
swap(u, v);
}
Modify(id[f1], id[u], val,);
u = fa[f1]; f1 = top[u];
}
if (deep[u] > deep[v]){
swap(u, v);
}
Modify(id[u], id[v],val, );
}
int Query(int pos, int k){
if (Seg[k].st == Seg[k].ed){
return Seg[k].val;
}
pushDown(k);
if (pos <= Seg[L(k)].ed){
return Query(pos, L(k));
}
else{
return Query(pos, R(k));
}
}
int main(){
//#ifdef kirito
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
//#endif
// int start = clock();
int n,m;
while (~scanf("%d",&n)){
Init();
for (int i = ; i < n; i++){
int u, v;
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
DFS1(, , ); DFS2(, ); Build(, n, );
scanf("%d", &m);
while (m--){
int u, v;
scanf("%d%d", &u, &v);
switch (u){
case : Modify(id[v], endid[v], , ); break;
case : Modify(v, , ); break;
default: printf("%d\n", Query(id[v], )); break;
}
}
}
//#ifdef LOCAL_TIME
// cout << "[Finished in " << clock() - start << " ms]" << endl;
//#endif
return ;
}
CodeForces - 343D 树链剖分的更多相关文章
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
- Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组
Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...
- CodeForces 191C 树链剖分 第4遍
非常无奈,模板重新无奈的打错了.. 只是,非常快便找到了.. 题意:给一些边,有一些操作,每次操作,都要在这些边上加上1,求每一个边的边权.. #include<cstdio> #incl ...
- CodeForces 343D water tree(树链剖分)
Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a res ...
- Codeforces 343D Water Tree & 树链剖分教程
原题链接 题目大意 给定一棵根为1,初始时所有节点值为0的树,进行以下三个操作: 将以某点为根的子树节点值都变为1 将某个节点及其祖先的值都变为0 *询问某个节点的值 解题思路 这是一道裸的树链剖分题 ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)
题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...
- Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分
D. Happy Tree Party Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/593/p ...
- 【Codeforces】【网络流】【树链剖分】【线段树】ALT (CodeForces - 786E)
题意 现在有m个人,每一个人都特别喜欢狗.另外还有一棵n个节点的树. 现在每个人都想要从树上的某个节点走到另外一个节点,且满足要么这个人自带一条狗m,要么他经过的所有边h上都有一条狗. 2<=n ...
- Codeforces 704E Iron Man [树链剖分,计算几何]
Codeforces 这题--真是搞死我了-- 好不容易下定了决心要不颓废,要写题,结果一调就调了十几个小时-- 思路 我们发现在树上做非常不舒服,于是树链剖分之后一次在重链上的移动就可以看做是在df ...
随机推荐
- springboot操作rabbitmq
////DirectExchange directExchange = new DirectExchange("test.direct");////amqpAdmin.declar ...
- 快速开发框架下载地址(github)
eladmin:https://github.com/elunez/eladmin bootDo:https://www.oschina.net/p/bootdo
- 034:DTL常用过滤器(3)
default过滤器: 如果值被评估为 False .比如 [] , "" , None , {} 等这些在 if 判断中为 False 的值,都会使用 default 过滤器提供 ...
- Cobaltstrike系列教程(二)-Listner与Payload生成 heatlevel
0x000-前文 Cobaltstrike系列教程(一)简介与安装 0x001-Listner(监听器)介绍 ①Cobaltstrike listner简介 可能有一些小白并不理解什么叫做listne ...
- Linux学习-基于CentOS7的MariaDB数据库的主从复制
一.MySQL主从复制原理 主从同步过程中主服务器有一个工作线程I/O dump thread,从服务器有两个工作线程I/O thread和SQL thread: 主服务器: dump Thread: ...
- SQLite和MySQL数据库的差别与应用
简单来说,SQLITE功能简约.小型化,追求最大磁盘效率:MYSQL功能全面,综合化.追求最大并发效率.假设仅仅是单机上用的,数据量不是非常大.须要方便移植或者须要频繁读/写磁盘文件的话.就用SQLi ...
- 数据库智能管理助手-CloudDBA
摘要:阿里云CloudDBA主要分为离线分析和在线分析两种功能.帮助用户节省成本,定位问题,分析原因并推荐解决方法.CloudDBA可以做到实时诊断,离线诊断和SQL优化.并且通过MySQL的参数调优 ...
- 变量类型,-数据类型(值类型,引用类型)uint 不有存负数,int,可以存负数,
俩种命名方法 1.Pascal 命名法,第一个字母大写其它字母小写Userid 2.Camel命名法,所有单第一方写大写,其它小写,骆峰命名法,userId 程序中元素的命名规范项目名:公司名.项目名 ...
- springboot参数校验
为了能够进行嵌套验证,必须手动在Item实体的props字段上明确指出这个字段里面的实体也要进行验证.由于@Validated不能用在成员属性(字段)上,但是@Valid能加在成员属性(字段)上,而且 ...
- 状压DP : [USACO06NOV]玉米田
玉米田 内存限制:128 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ ...