Codechef Observing the Tree
Chef gives you a tree, consisting of N nodes. The nodes are numbered from 1 to N, and each node has an integer, which is equal to 0 initially. Then, Chef asks you to perform M queries.
The first type of queries is changing: here, you are given integers X, Y, A and B. Add Ato the integer, associated with the node X, then add A+B to the integer, associated with the second node on the way from X to Y, then add A+2*B to the integer, associated with the third node on the way from X to Y, and so on. As you know, there is only one simple path from X to Y.
The second type of queries is a question: here, you are given integers X and Y. Output the sum of all integers, associated with nodes on the way from X to Y.
The third type of queries is a rollback: here, you are given an integer X. All the integers associated with the nodes return to the state after the X-th changing query. If X is 0, then all of them become equal to zero, as in the very beginning.
Input
The first line of an input consists of two integers - N and M.
Then, N−1 lines follow. These N−1 lines describe the tree structure. Each line consists of two integers - X and Y, and that means that there is an edge between node X and node Y.
Then, M lines follow. A single line denotes a single query, which has one of the following forms: (See the sample for the detailed explanation)
- c X1 Y1 A B - changing query,
- q X1 Y1 - question query,
- l X1 - rollback query.
As you can see, the numbers X and Y aren't given to you directly. For the rollbackquery, actual number X will be equal to (X1+lastans) modulo (total number ofchanging queries before this query + 1). For the changing and question queries, Xwill be equal to ((X1+lastans) modulo N)+1 and Y will be equal to ((Y1+lastans) modulo N)+1, where lastans denotes the last number that you have output, or zero if you haven't output any numbers yet.
Output
For each question query output the answer on a single line.
Constraints
- 1 ≤ N, M ≤ 100000 (105)
- 0 ≤ A, B ≤ 1000
- 0 ≤ X1, Y1 ≤ 100000 (105)
Example
Input:
5 7
1 2
2 3
3 4
4 5
c 1 4 2 3
c 2 3 5 10
q 1 3
l 1
q 1 3
l 1
q 1 3 Output:
35
0
15
Explanation
As you can see, the tree in the sample is like a line. Let's denote the first state of integers 0 0 0 0 0, where the i-th integer means the integer associated with the node i.
In the first changing query "c 1 4 2 3", the actual numbers are X = (1 + 0) modulo 5 + 1 = 2, Y = (4 + 0) modulo 5 + 1 = 5. Hence the state will be 0 2 5 8 11 after this query.
After the second changing query "c 2 3 5 10", the state will be 0 2 10 23 11 for similar reason.
In the next question query, the actual numbers are X = (1 + 0) modulo 5 + 1 = 2, Y = (3 + 0) modulo 5 + 1 = 4. Hence the answer must be 2 + 10 + 23 = 35.
In the first rollback query "l 1", the actual number is X = (1 + 35) modulo (2 + 1) = 36 modulo 3 = 0, since lastans = 36. Thus the state will be rollbacked to 0 0 0 0 0.
Then the answer of the next question query "q 1 3" must be 0, because all integers are currently 0.
In the second rollback query "l 1", the actual number is X = (1 + 0) modulo (2 + 1) = 1, since lastans = 0. Thus the state will be 0 2 5 8 11, which is the state after the firstchanging query.
Then the answer of the last question query must be 2 + 5 + 8 = 15.
题意:
一棵树,3个操作:
树上两点之间加一个等差数列,
查询树上两点之间权值和,
回到某次修改之后的状态
思路:树链剖分+主席树
#include<cstdio>
#include<algorithm>
#define N 100001
using namespace std;
int root[N],lc[N*],rc[N*];
int fa[N],deep[N],bl[N],son[N],id[N],cnt;
long long k[N*],b[N*],sum[N*];
int front[N],nxt[N*],to[N*],tot;
long long A,B,QA,QB,ans;
int QL,QR;
int sum_chan,now,n,m;
int read()
{
int x=; char c=getchar();
while(c<''||c>'') c=getchar();
while(c>=''&&c<='') { x=x*+c-''; c=getchar(); }
return x;
}
struct TREE
{
long long get_sum(long long kk,long long bb,int n)
{
return (bb+bb+kk*(n-))*n/;
}
void change(int y,int &x,int l,int r)
{
x=++tot;
lc[x]=lc[y];
rc[x]=rc[y];
k[x]=k[y];
b[x]=b[y];
sum[x]=sum[y];
if(l>=QL&&r<=QR)
{
sum[x]+=get_sum(QB,(l-QL)*QB+QA,r-l+);
k[x]+=QB;
b[x]+=(l-QL)*QB+QA;
return;
}
int ll=max(QL,l),rr=min(QR,r);
sum[x]+=get_sum(QB,QA+QB*(ll-QL),rr-ll+);
int mid=l+r>>;
if(QL<=mid) change(lc[y],lc[x],l,mid);
if(QR>mid) change(rc[y],rc[x],mid+,r);
}
void query(int x,int l,int r)
{
if(!x) return;
if(QL<=l&&QR>=r)
{
ans+=sum[x];
return;
}
int ll=max(l,QL),rr=min(r,QR);
ans+=get_sum(k[x],b[x]+k[x]*(ll-l),rr-ll+);
int mid=l+r>>;
if(QL<=mid) query(lc[x],l,mid);
if(QR>mid) query(rc[x],mid+,r);
}
}Tree;
struct CHAIN
{
void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
}
void dfs1(int x,int f)
{
son[x]++;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=f)
{
fa[to[i]]=x;
deep[to[i]]=deep[x]+;
dfs1(to[i],x);
son[x]+=son[to[i]];
}
}
void dfs2(int x,int top)
{
id[x]=++cnt;
bl[x]=top;
int y=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x]&&son[to[i]]>son[y]) y=to[i];
if(!y) return;
dfs2(y,top);
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x]&&to[i]!=y) dfs2(to[i],to[i]);
}
int LCA(int x,int y)
{
while(bl[x]!=bl[y])
{
if(deep[bl[x]]<deep[bl[y]]) swap(x,y);
x=fa[bl[x]];
}
if(deep[x]>deep[y]) return y;
return x;
}
void change(int x,int y,int dis)
{
int l=,r=dis;
while(bl[x]!=bl[y])
{
if(deep[bl[x]]>deep[bl[y]])
{
QL=id[bl[x]]; QR=id[x];
QA=A+(l+QR-QL)*B;
QB=-B;
Tree.change(root[sum_chan],root[sum_chan],,n);
x=fa[bl[x]];
l+=QR-QL+;
}
else
{
QL=id[bl[y]]; QR=id[y];
QA=A+(r-(QR-QL))*B;
QB=B;
Tree.change(root[sum_chan],root[sum_chan],,n);
y=fa[bl[y]];
r-=QR-QL+;
}
}
if(deep[x]<deep[y])
{
QL=id[x]; QR=id[y];
QA=A+l*B;
QB=B;
Tree.change(root[sum_chan],root[sum_chan],,n);
}
else
{
QL=id[y]; QR=id[x];
QA=A+r*B;
QB=-B;
Tree.change(root[sum_chan],root[sum_chan],,n);
}
}
void query(int x,int y)
{
while(bl[x]!=bl[y])
{
if(deep[bl[x]]<deep[bl[y]]) swap(x,y);
QL=id[bl[x]]; QR=id[x];
Tree.query(root[now],,n);
x=fa[bl[x]];
}
if(deep[x]>deep[y]) swap(x,y);
QL=id[x]; QR=id[y];
Tree.query(root[now],,n);
}
}Chain;
int main()
{
/*freopen("data.txt","r",stdin);
freopen("my.txt","w",stdout);*/
n=read(); m=read();
int u,v;
for(int i=;i<n;i++)
{
scanf("%d%d",&u,&v);
Chain.add(u,v);
}
Chain.dfs1(,);
Chain.dfs2(,);
tot=; char ch[]; int dis;
while(m--)
{
scanf("%s",ch);
if(ch[]=='c')
{
root[++sum_chan]=root[now];
u=read(); v=read(); A=read(); B=read();
u=(u+ans)%n+; v=(v+ans)%n+;
dis=deep[u]+deep[v]-*deep[Chain.LCA(u,v)];
Chain.change(u,v,dis);
now=sum_chan;
}
else if(ch[]=='q')
{
u=read(); v=read();
u=(u+ans)%n+; v=(v+ans)%n+;
ans=;
Chain.query(u,v);
printf("%lld\n",ans);
}
else
{
u=read();
u=(u+ans)%(sum_chan+);
now=u;
}
}
}
Codechef Observing the Tree的更多相关文章
- Codechef Union on Tree
Codechef Union on Tree https://www.codechef.com/problems/BTREE 简要题意: 给你一棵树,\(Q\)次询问,每次给出一个点集和每个点的\(r ...
- [CodeChef-QUERY]Observing the Tree
题目大意: 给你一棵树,一开始每个点的权值都是0,要求支持一下三种操作: 1.路径加等差数列. 2.路径求和. 3.回到以前的某次操作. 强制在线. 思路: 树链剖分+主席树. 最坏情况下,n个点的树 ...
- 【点分树】codechef Yet Another Tree Problem
已经连咕了好几天博客了:比较经典的题目 题目大意 给出一个 N 个点的树和$K_i$, 求每个点到其他所有点距离中第 $K_i$ 小的数值. 题目分析 做法一:点分树上$\log^3$ 首先暴力做法: ...
- Codechef Chef Cuts Tree
该思博的时候就思博到底,套路的时候不能再套路的一道题 首先我们将联通块的大小平方和进行转化,发现它就等价于连通点对数,而这个可以转化为连接两点的边数(距离)和 所以我们考虑第\(i\)天时,一个点对\ ...
- @codechef - KILLER@ Painting Tree
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N 个点的有根树,标号 1 到 N,以 1 为根.定义 ...
- ZJOI2019Round#2
乱听课记录 关于树的分治问题&杂题选讲 张哲宇 边分治 (边分不是很鸡肋吗) 例题一 题目大意:给出两颗有正负边权的树,求出两个点\(u,v\)使得两棵树中\((u,v)\)距离的和最大. ...
- BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )
树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...
- 【启发式搜索】Codechef March Cook-Off 2018. Maximum Tree Path
有点像计蒜之道里的 京东的物流路径 题目描述 给定一棵 N 个节点的树,每个节点有一个正整数权值.记节点 i 的权值为 Ai.考虑节点 u 和 v 之间的一条简单路径,记 dist(u, v) 为其长 ...
- Codechef March Cook-Off 2018. Maximum Tree Path
目录 题意 解析 AC_code @(Codechef March Cook-Off 2018. Maximum Tree Path) 题意 给你一颗\(n(1e5)\)个点有边权有点权的树,\(Mi ...
随机推荐
- scrum立会报告+燃尽图(第三周第一次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://coding.net/u/wuyy694 ...
- 欢迎来怼-----Beta冲刺贡献分数分配结果
队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文
- c# 导入第三方插件(例如pdf控件),莫名有时候成功有时候出错
问题情境: 正如标题所述: 解决办法: 怀疑是adobe acrobat 9 pro安装文件出错:重新安装,成功. 在这过程中,尝试过福听阅读器,adobe reader等,均正常. 注:1.第三方的 ...
- Java微笔记(5)
final关键字 super关键字
- 配置resin web方式部署项目
写在前面,推荐下载resin4.0.47版本.其它版本没有测试 最近打算做一个小项目,然后容器选用了resin.想通过web提交war文件的方式 进行部署,更新代码也方便. 试了resin最新的版本( ...
- Spring管理过滤器:org.springframework.web.filter.DelegatingFilterProxy
配置web.xml <filter> <filter-name>springSecurityFilterChain</filter-name> ...
- Scala快速入门-函数组合
compose&andThen 两个函数组装为一个函数,compose和andThen相反 def f(test: String):String = { "f(" + te ...
- 结对编程--fault,error,failure的程序设计
一.结对编程内容: 1.不能触发Fault. 2.触发Fault,但是不触发Error. 3.触发Error,但不触发Failure. 二.结对编程人员 1.周浩,周宗耀 2.结对截图: 三.结对项目 ...
- HDU 2113 Secret Number
http://acm.hdu.edu.cn/showproblem.php?pid=2113 Problem Description 有一天, KIKI 收到一张奇怪的信, 信上要KIKI 计算出给定 ...
- UVALive6434_Number Assignment
简单dp题. 这样的,意思为给你n个数,要你现在将这n个数分为m组,使得所有组内最大值与最小值的差的和最小. 其实可以这样来考虑这个问题,首先可以把所有的数字从小到大排个序,显然如果有一种取法是最优的 ...