题目链接  ...Wait for it...

考虑树链剖分。

对于树上的每个点开一个set,记录当前该节点上所有的girls。

每个节点初始的权值为set中的最小值。

询问的时候每次在路径上寻找最小值,并返回这个点的编号。

然后把这个点的set的第一个元素取出,换成下一个元素。

因为女孩总数不超过1e5,所以总查询次数不会超过1e5

修改操作用lazy标记就可以了。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define lson i << 1, L, mid
#define rson i << 1 | 1, mid + 1, R
#define ls i << 1
#define rs i << 1 | 1
#define MP make_pair
#define fi first
#define se second typedef long long LL;
typedef pair <LL, int> PII; const int N = 1e5 + 10;
const LL inf = 1e18; int n, m, q;
int id, cnt = 0;
int ret[N];
int at[N], sz[N], son[N], top[N], f[N], in[N], out[N], deep[N], father[N];
vector <int> v[N];
set <PII> s[N];
LL lazy[N << 2];
PII t[N << 2]; void dfs(int x, int fa, int dep){
sz[x] = 1;
son[x] = 0;
father[x] = fa;
deep[x] = dep;
for (auto u : v[x]){
if (u == fa) continue;
dfs(u, x, dep + 1);
sz[x] += sz[u];
if (sz[son[x]] < sz[u]) son[x] = u;
}
} void dfs2(int x, int tp){
top[x] = tp;
in[x] = f[x] = ++id;
if (son[x]) dfs2(son[x], tp);
for (auto u : v[x]){
if (u == father[x] || u == son[x]) continue;
dfs2(u, u);
}
out[x] = id;
} void pushup(int i){
t[i] = min(t[ls], t[rs]);
} void pushdown(int i){
if (lazy[i]){
lazy[ls] += lazy[i];
lazy[rs] += lazy[i];
t[ls].fi += lazy[i];
t[rs].fi += lazy[i];
lazy[i] = 0;
}
} void build(int i, int L, int R){
lazy[i] = 0;
if (L == R){
t[i] = *s[L].begin();
return;
} int mid = (L + R) >> 1;
build(lson);
build(rson);
pushup(i);
} void update(int i, int L , int R , int l, int r, LL val){
if (l <= L && R <= r){
lazy[i] += val;
t[i].fi += val;
return;
} pushdown(i);
int mid = (L + R) >> 1 ;
if (l <= mid) update(lson, l, r, val);
if (r > mid) update(rson, l, r, val);
pushup(i);
} void modify(int i, int L, int R, int x){
if (L == R){
s[L].erase(s[L].begin());
t[i] = *s[L].begin();
t[i].fi += lazy[i];
return;
}
pushdown(i);
int mid = (L + R) >> 1 ;
if (x <= mid) modify(lson, x) ;
else modify(rson, x);
pushup(i);
} PII query(int i, int L, int R, int l, int r){
if (l <= L && R <= r) return t[i];
pushdown(i);
int mid = (L + R) >> 1 ;
if (r <= mid) return query(lson, l, r);
if (l > mid) return query(rson, l, r);
return min(query(lson, l, r), query(rson, l, r));
} int Query(int x, int y){
PII ans = PII(inf, 0);
while (top[x] ^ top[y]){
if (deep[top[x]] < deep[top[y]]) swap(x, y);
ans = min(ans, query(1, 1, n, f[top[x]], f[x]));
x = father[top[x]];
}
if (deep[x] > deep[y]) swap(x, y);
ans = min(ans, query(1, 1, n, f[x], f[y]));
return ans.se;
} int main(){ scanf("%d%d%d", &n, &m, &q);
rep(i, 2, n){
int x, y;
scanf("%d%d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
} dfs(1, 0, 0);
dfs2(1, 1); rep(i, 1, n) s[i].insert(MP(inf, 0));
at[0] = N - 1; rep(i, 1, m){
int x;
scanf("%d", &x);
at[i] = x;
s[f[x]].insert(MP(i, i));
} build(1, 1, n); while (q--){
int op, x, y, lim;
LL val;
scanf("%d", &op);
if (op == 2){
scanf("%d%lld", &x, &val);
update(1, 1, n, in[x], out[x], val);
}
else{
scanf("%d%d%d", &x, &y, &lim);
cnt = 0;
while (lim--){
int idx = Query(x, y);
if (idx == 0) break;
ret[++cnt] = idx;
modify(1, 1, n, f[at[idx]]);
}
printf("%d", cnt);
rep(i, 1, cnt) printf(" %d", ret[i]);
putchar(10);
}
} return 0;
}

Codeforces 696E ...Wait for it...(树链剖分)的更多相关文章

  1. CodeForces 916E Jamie and Tree(树链剖分+LCA)

    To your surprise, Jamie is the final boss! Ehehehe. Jamie has given you a tree with n vertices, numb ...

  2. Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)

    题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...

  3. 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 ...

  4. 【Codeforces】【网络流】【树链剖分】【线段树】ALT (CodeForces - 786E)

    题意 现在有m个人,每一个人都特别喜欢狗.另外还有一棵n个节点的树. 现在每个人都想要从树上的某个节点走到另外一个节点,且满足要么这个人自带一条狗m,要么他经过的所有边h上都有一条狗. 2<=n ...

  5. 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 ...

  6. Codeforces 704E Iron Man [树链剖分,计算几何]

    Codeforces 这题--真是搞死我了-- 好不容易下定了决心要不颓废,要写题,结果一调就调了十几个小时-- 思路 我们发现在树上做非常不舒服,于是树链剖分之后一次在重链上的移动就可以看做是在df ...

  7. D. Happy Tree Party CodeForces 593D【树链剖分,树边权转点权】

    Codeforces Round #329 (Div. 2) D. Happy Tree Party time limit per test 3 seconds memory limit per te ...

  8. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  9. CodeForces - 343D 树链剖分

    题目链接:http://codeforces.com/problemset/problem/343/D 题意:给定一棵n个n-1条边的树,起初所有节点权值为0,然后m个操作. 1 x:把x为根的子树的 ...

随机推荐

  1. PHP网站实现地址URL重定向

    网站建设中,通常会用到网站地址URL的重定向,这样的好处是有利于你网站的SEO优化,也就是让你的网站实现伪静态,下面简单介绍一下实现的两种方法: 1.在Apache配置文件中设置重定向 首先找到Apa ...

  2. 【结构型模式】《大话设计模式》——读后感 (12)在NBA我需要翻译?——适配器模式

    适配器模式:将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能在一起工作的 那些类可以在一起工作了[DP] UML类图: 简单模拟一下代码: //已存在的.具有 ...

  3. scanf(),gets(),getchar()

    scanf()与gets()区别: scanf( )函数和gets( )函数都可用于输入字符串,但在功能上有区别.若想从键盘上输入字符串"hi hello",则应该使用gets() ...

  4. 深入Python底层,谈谈内存管理机制

    说到内存管理,就先说一下垃圾回收吧.垃圾回收是Python,Java等语言管理内存的一种方式,说的直白些,就是清除无用的垃圾对象.C语言及C++中,需要通过malloc来进行内存的申请,通过free而 ...

  5. pl/sql的控制结构,分支、循环、控制

    一.pl/sql的进阶--控制结构在任何计算机语言(c,java,pascal)都有各种控制语句(条件语句,循环结构,顺序控制结构...),在pl/sql中也存在这样的控制结构.在本部分学习完成后,希 ...

  6. deque 类

    题外: 'A' +1='B' 1.deque被称为双端队列,它也是一种顺序容器.可通过迭代器存取元素 ,也可以通过下标顺序 存取元素 for(i=0;i<d1.size();i++) { cou ...

  7. 在Asp.net MVC中添加一个全局的异常处理的过滤器及Log4Net的使用

    1:捕获异常新建一个异常处理的类MyExceptionAttribute捕获异常信息. //写到日志中.多个线程同时操作一个文件,造成文件的并发,这时用队列 public static Queue&l ...

  8. 九度oj 题目1411:转圈

    题目描述: 在一个有向图有n个顶点(编号从1到n),给一个起点s,问从起点出发,至少经过一条边,回到起点的最短距离. 输入: 输入包括多组,每组输入第一行包括三个整数n,m,s(1<=n< ...

  9. 【bzoj2698】染色 期望

    题目描述 输入 输入一行四个整数,分别为N.M.S和T. 输出 输出一行为期望值,保留3位小数. 样例输入 5 1 2 3 样例输出 2.429 题解 期望 由于期望在任何时候都是可加的,因此只要算出 ...

  10. 【Luogu】P2486染色(树链剖分)

    题目链接 线段树维护左端颜色,右端颜色,颜色段数量. 合并的时候看左子树的右端颜色是不是等于右子树的左端颜色,如果等于那么颜色段数量要-1S 然后在树剖跳链的时候搞同样的操作qwq 然后就没有然后了 ...