TTTTTTTTTTTT Gym 100818B Tree of Almost Clean Money 树连剖分+BIT 模板题
Problem B
Tree of Almost Clean Money
Input File: B.in
Output File: standard output
Time Limit: 4 seconds (C/C++)
Memory Limit: 256 megabytes
The tree of Almost Clean Money (or ACM Tree, for short) consists of N (1≤N≤500000) vertices in
which, well, (almost clean) money is growing (contrary to the old saying that money doesn’t grow
on trees). The vertices are numbered from 0 to N-1, with vertex 0 being the root of the tree. Every
vertex i except vertex 0 has a parent p(i) in the tree, such that p(i)<i. Initially, every vertex
contains v(i) (0≤v(i)<1000000007) monetary units. Due to its special properties, the tree has
attracted the attention of a large money laundering organization, who wants to use the tree for its
money “cleansing” business. This organization wants to execute Q (1≤Q≤50000) operations on
the tree. Each operation consists of two steps:
1) In step 1, K (1≤K≤1000) vertices from the tree are chosen: x(1), …, x(K) (0≤x(i)≤N-1) –
the same vertex may be selected multiple times here. In each of these vertices, an
amount of monetary units is added (thus increasing the amount of monetary units in
them). More exactly, y(i) (0≤y(i)<1000000007) monetary units are added to the selected
vertex x(i) (1≤i≤K).
2) In step 2, two vertices u and v (0≤u,v≤N-1) are chosen and the organization wants to
know the total amount of money found in the vertices located on the unique path in the
tree between the vertices u and v (with u and v inclusive).
The organization hired you to find the answer for step 2 of each of the Q operations and promised
you a hefty amount of money if you succeed.
Input
The first line of input contains the number of tree vertices N. The next N-1 lines contain two
space-separated integers, p(i) and i, each describing an edge of the tree. The next line contains
N space-separated values: the initial amount of monetary units in each vertex, v(0), …, v(N-1).
The next line contains the number of operations Q. Each of the next Q lines describes an
operation. Each operation is described by 9 space-separated integers, in this order: K, x(1), y(1),
A, B, C, D, u, v (0≤A,B,C,D<1000000007). The values x(2≤i≤K) and y(2≤i≤K) are generated as
follows:
x(i) = (A*x(i-1) + B) modulo N
y(i) = (C*y(i-1) + D) modulo 1000000007
Output
For each of the Q operations print a line containing the answer to step 2 of the operation. When
computing the answer for an operation, the effects of steps 1 from previous operations need to be
considered, too (i.e. after adding y(i) monetary units to a vertex x(i), these units remain added to
the vertex when executing subsequent operations, too).
acm
Sample input Sample output Explanation
4
0 1
0 3
1 2
1 2 3 4
3
1000 1 1 1 0 1 0 0 2
2 0 5 1 1 2 2 2 3
1 3 7 999 999 999 999 1 3
1006
1027
1031
In the first operation the value 1 is added
1000 times to vertex 1 (note A=C=1,
B=D=0). The path between 0 and 2
contains the vertices 0, 1 and 2. The total
amount of monetary units in them is 1006.
In operation 2: x(1)=0, y(1)=5, x(2)=1,
y(2)=12. The path between 2 and 3 contains
all the vertices of the tree.
In operation 3: K=1, so A, B, C, D are
irrelevant.
题意:给你一棵n个节点的树(n<=5e5),现在可以进行至多Q次操作(Q<=5e4),每次至多可以给k个节点(k<=1000)增加一个数值,然后每个操作都有一个询问(u,v),问从u到v的简单路径上的节点权值和。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
#define MM(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
#define CT continue
#define SC scanf
const int N=5*1e5+10;
const double pi=acos(-1); int n,siz[N],dep[N],son[N],treepos[N],
top[N],par[N],x[1005],y[1005];
ll tree[N];
vector<int> G[N]; void add_edge(int u,int v)
{
G[u].push_back(v);
G[v].push_back(u);
} int dfs_clock; void dfs1(int u,int father,int depth)
{
siz[u]=1;
dep[u]=depth;
son[u]=-1;
par[u]=father;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(v==father) CT;
dfs1(v,u,depth+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[v]>siz[son[u]])
son[u]=v;
}
} void dfs2(int u,int tp)
{
top[u]=tp;
treepos[u]=++dfs_clock;
if(son[u]==-1) return;
dfs2(son[u],tp);
for(int i=0;i<G[u].size();i++) {
int v=G[u][i];
if(v==par[u]||v==son[u]) CT;
dfs2(v,v);
}
} int lowbit(int i)
{
return (i&(-i));
} void add(int pos,int val)
{
while(pos<=n) {
tree[pos]+=val;
pos+=lowbit(pos);
}
} ll tfind(int x)
{
ll res=0;
while(x>=1){
res+=tree[x];
x-=lowbit(x);
}
return res;
} ll query(int a,int b)
{
if(a>b) swap(a,b);
return tfind(b)-tfind(a-1);
} ll ans(int u,int v)
{
ll res=0,tu=top[u],tv=top[v];
while(tu!=tv) {
if(dep[tu]<dep[tv]){
swap(tu,tv);
swap(u,v);
}
int l=treepos[tu],r=treepos[u];
res+=query(l,r);
u=par[tu];
tu=top[u];
}
if(dep[u]<dep[v]) swap(u,v);
res+=query(treepos[v],treepos[u]);
return res;
} int main()
{
while(~SC("%d",&n))
{
for(int i=1;i<=n;i++) G[i].clear();
for(int i=1;i<n;i++) {
int u,v;
SC("%d%d",&u,&v);
add_edge(u+1,v+1);
} MM(tree,0);
dfs_clock=0; dfs1(1,0,1);
dfs2(1,1); for(int i=1;i<=n;i++) {
int x;SC("%d",&x);
add(treepos[i],x);
} int q;
SC("%d",&q);
while(q--){
int k,u,v;ll A,B,C,D;
SC("%d%d%d%lld%lld%lld%lld%d%d",&k,&x[1],&y[1],&A,&B,&C,&D,&u,&v);
add(treepos[x[1]+1],y[1]);
for(int i=2;i<=k;i++){
x[i]=(A*x[i-1]+B)%n;
y[i]=(C*y[i-1]+D)%1000000007;
add(treepos[x[i]+1],y[i]);
}
printf("%lld\n",ans(u+1,v+1));
} }
return 0;
}
分析:学了下树链剖分,树连剖分主要是用于对树进行路径求和统计以及去最大值最小值之类的,第一次dfs,找到重儿子,并给
节点深度表好号,记录下每个节点额父节点,,第二次dfs,构建树链,同时建好BIT或线段树,,最后然后路径求和的时候,先要统计链顶节点深度大的。
TTTTTTTTTTTT Gym 100818B Tree of Almost Clean Money 树连剖分+BIT 模板题的更多相关文章
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- 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 ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST
E. Minimum spanning tree for each edge Connected undirected weighted graph without self-loops and ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)
题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...
- 【 Gym - 101138J 】Valentina and the Gift Tree(树链剖分)
BUPT2017 wintertraining(15) 4 D Gym - 101138J 数据 题意 n个节点的一棵树,每个节点的权值为g,q个询问,树上的节点U-V,求U到V的路径的最大子段和. ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
- 【BZOJ-4353】Play with tree 树链剖分
4353: Play with tree Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 31 Solved: 19[Submit][Status][ ...
- poj 3321:Apple Tree(树状数组,提高题)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18623 Accepted: 5629 Descr ...
随机推荐
- 【Python基础】09_Python中的元组
1.元组的定义 Tuple (元组)与列表类似,元组的元素 不能修改 元组通常保存 不同类型 的数据 元组用()定义 info_tuple = ("张三", 18, 1.75) 定 ...
- Java学习总结一 数据类型
@Java300 学习总结 一.Java 基本数据类型分类如下: 整型变量:byte.short.int.long 浮点型变量:float.double 字符型变量:char 布尔型变量:boolea ...
- Go语言之依赖管理
Go语言之依赖管理 Go语言的依赖管理随着版本的更迭正逐渐完善起来. 依赖管理 为什么需要依赖管理 最早的时候,Go所依赖的所有的第三方库都放在GOPATH这个目录下面.这就导致了同一个库只能保存一个 ...
- nginx浏览器开启密码验证
如果我们在 nginx 下搭建了一些站点,但是由于站点内容或者流量的关系,我们并不想让所有人都能正常访问,那么我们可以设置访问认证.只有让用户输入正确的用户名和密码才能正常访问.效果如下: 在 ngi ...
- Wannafly挑战赛22
B. 字符路径 给一个含n个点m条边的有向无环图(允许重边,点用1到n的整数表示),每条边上有一个字符,问图上有几条路径满足路径上经过的边上的字符组成的的字符串去掉空格后以大写字母开头,句号 '.' ...
- 解决 vue 使用 element 时报错ERROR in ./node_modules/element-ui/lib/theme-chalk/fonts/element-icons.ttf
在 webpack.config.js 中加入这个依赖 { test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/, loader: 'file-loader' }
- Jerry Wang在SAP社区上获得的徽章
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
- 使用jMeter构造大量并发的随机HTTP请求
在前一篇文章使用jMeter构造大量并发HTTP请求进行微服务性能测试里,我介绍了如何用jMeter构造并发HTTP请求.但是通过文中介绍的方式构造的并发请求,其请求参数都是硬编码的'Wang'. 有 ...
- VIM从原理上认识^M问题
问题背景 VIM在打开文件的时候如果遇到两种换行符风格(dos与unix)共存的文件,通常会在行尾显示出烦人的^M.如果^M较少,比较容易定位到哪几行出了问题,但是如果^M较多,就很难搞.下面先给出解 ...
- Celery 初步使用心得
一. 基本介绍 Celery是一个专注于实时处理和任务调度的分布式任务队列.所谓任务就是消息,消息中的有效载荷中包含要执行任务需要的全部数据. 使用Celery常见场景: Web应用.当用户触发的一个 ...