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 ...
随机推荐
- zabbix agentd错误日志解决办法
公司新上了一台服务器,我安装了zabbix_agents软件包,并复制了zabbix server端的zabbix_agentd.conf到/etc/zabbix里面并修改了相关的参数,并启动了zab ...
- Spring---数据访问
1.Spring Data概述 1.1.Spring Data 项目 是 Spring用来解决数据访问问题 的一站式解决方案,包含了 大量关系型数据库.非关系型数据库 的 数据访问解决方案 ...
- R reticulate 设置 python 环境
library("reticulate") use_python("/usr/bin/python", required = T) py_config() 注意 ...
- Python3解leetcode N-ary Tree Level Order Traversal
问题描述: Given an n-ary tree, return the level order traversal of its nodes' values. (ie, from left to ...
- Word文档粘贴到帝国CMS
很多时候我们用一些管理系统的时候,发布新闻.公告等文字类信息时,希望能很快的将word里面的内容直接粘贴到富文本编辑器里面,然后发布出来.减少排版复杂的工作量. 下面是借用百度doc 来快速实现这个w ...
- Python_005(字典无极坑)
一.字典(dict) 1.字典的定义格式:dic{key1:value1,key2,value2} :这里面key是唯一的,保存的时候,根据key计算一个内存地址,然后将key-value保存在这个地 ...
- git config使用
我们知道config是配置的意思,那么git config命令就是对git进行一些配置.而配置一般都是写在配置文件里面,那么git的配置文件在哪里呢?互动一下,先问下大家. 你们所知的git配置文件是 ...
- 28 August
单调队列复习. 投资 (invest) 给定一带符号整数数列,求长度为 \([s, e]\) 的子区间的和的最大值.(最大子段和) 降二维为一维,for循环枚举区间右端点.预处理前缀和,问题转化为找到 ...
- GCD 和 NSOperationQueue 的差别
http://stackoverflow.com/questions/10373331/nsoperation-vs-grand-central-dispatch http://www.cocoach ...
- 网站名,服务器名,url,ip,域名的区别和联系。
平时我们可能容易混淆这几个名词含义,今天我打算捋一捋这几个概念. 我们知道,两台计算机要想互相通信,就像古代写信一样,地址必须要唯一的,不然就会出错.计算机之间通信也是一样的,要保证计算机的地址的唯一 ...