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 ...
随机推荐
- 封装 pyinstaller -F -i b.ico excel.py
安装pywin32,可以参考<怎么给python安装pywin32模块?> 一定要注意对应的python版本,否则不能安装. 5怎么给python安装pywin32模块? 2 用命 ...
- 怎么实现web端上传超大文件
1.介绍enctype enctype 属性规定发送到服务器之前应该如何对表单数据进行编码. enctype作用是告知服务器请求正文的MIME类型(请求消息头content-type的作用一样) 1. ...
- [14th CSMO Day 1 <平面几何>]
关于LowBee苦思冥想的结果(仅供参考):
- Python Web框架本质——Python Web开发系列一
前言:了解一件事情本质的那一瞬间总能让我获得巨大的愉悦感,希望这篇文章也能帮助到您. 目的:本文主要简单介绍Web开发中三大基本功能:Socket实现.路由系统.模板引擎渲染. 进入正题. 一. 基础 ...
- Flutter中的浮动按钮 FloatingActionButton
FloatingActionButton 简称 FAB ,可以实现浮动按钮,也可以实现类似闲鱼 app 的底部凸起导航 . 常用属性 FloatingActionButton的常用属性,同flutte ...
- 谜之WA
完全k叉树 谜之WA #include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; ll k,n; ...
- 微信小程序的开发框架
wxss:是一套样式语言,用来描述wxml的组件样式:小程序在css基础上做的修改和扩充的版本 css:是一套样式语言,样式表,用来描述xml和html文件样式的呈现: 设备像素:是图片在设备上显示的 ...
- python 数字系列-复数的数学运算
复数的数学运算 问题 你写的最新的网络认证方案代码遇到了一个难题,并且你唯一的解决办法就是使用复数空间. 再或者是你仅仅需要使用复数来执行一些计算操作. 解决方案 复数可以用使用函数 complex( ...
- MIME TYPE是什么?
首先,我们要了解浏览器是如何处理内容的.在浏览器中显示的内容有 HTML.有 XML.有 GIF.还有 Flash ……那么,浏览器是如何区分它们,决定什么内容用什么形式来显示呢?答案是 MIME T ...
- Netty精进01
为什么要学习Netty? 目前基于Netty实现的一些优秀的开源框架:Dubbo.RocketMQ.Spark.Spring5.Flink.ElasticSearch.gRPC……这些还说明不了为什么 ...