Home » Practice(Hard) » Observing the Tree
 

Observing the Tree Problem Code: QUERY

Submit

All submissions for this problem are available.

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的更多相关文章

  1. Codechef Union on Tree

    Codechef Union on Tree https://www.codechef.com/problems/BTREE 简要题意: 给你一棵树,\(Q\)次询问,每次给出一个点集和每个点的\(r ...

  2. [CodeChef-QUERY]Observing the Tree

    题目大意: 给你一棵树,一开始每个点的权值都是0,要求支持一下三种操作: 1.路径加等差数列. 2.路径求和. 3.回到以前的某次操作. 强制在线. 思路: 树链剖分+主席树. 最坏情况下,n个点的树 ...

  3. 【点分树】codechef Yet Another Tree Problem

    已经连咕了好几天博客了:比较经典的题目 题目大意 给出一个 N 个点的树和$K_i$, 求每个点到其他所有点距离中第 $K_i$ 小的数值. 题目分析 做法一:点分树上$\log^3$ 首先暴力做法: ...

  4. Codechef Chef Cuts Tree

    该思博的时候就思博到底,套路的时候不能再套路的一道题 首先我们将联通块的大小平方和进行转化,发现它就等价于连通点对数,而这个可以转化为连接两点的边数(距离)和 所以我们考虑第\(i\)天时,一个点对\ ...

  5. @codechef - KILLER@ Painting Tree

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N 个点的有根树,标号 1 到 N,以 1 为根.定义 ...

  6. ZJOI2019Round#2

    乱听课记录 关于树的分治问题&杂题选讲 张哲宇 边分治 (边分不是很鸡肋吗) 例题一 题目大意:给出两颗有正负边权的树,求出两个点\(u,v​\)使得两棵树中\((u,v)​\)距离的和最大. ...

  7. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

  8. 【启发式搜索】Codechef March Cook-Off 2018. Maximum Tree Path

    有点像计蒜之道里的 京东的物流路径 题目描述 给定一棵 N 个节点的树,每个节点有一个正整数权值.记节点 i 的权值为 Ai.考虑节点 u 和 v 之间的一条简单路径,记 dist(u, v) 为其长 ...

  9. Codechef March Cook-Off 2018. Maximum Tree Path

    目录 题意 解析 AC_code @(Codechef March Cook-Off 2018. Maximum Tree Path) 题意 给你一颗\(n(1e5)\)个点有边权有点权的树,\(Mi ...

随机推荐

  1. (Miller Rabin算法)判断一个数是否为素数

    1.约定 x%y为x取模y,即x除以y所得的余数,当x<y时,x%y=x,所有取模的运算对象都为整数. x^y表示x的y次方.乘方运算的优先级高于乘除和取模,加减的优先级最低. 见到x^y/z这 ...

  2. Hibernate(六)

    三套查询之HQL查询 hql语句(面向):类   对象   属性 package com.rong.entity.hql; public class User { public User(int id ...

  3. 敏捷开发之Scrum站立会议

    Scrum是迭代式增量软件开发过程,通常用于敏捷开发.站立会议通常指Scrun方法中的每日站立会议.顾名思义,是每天以站姿的方式召开的会议.以下从功能及要点方面对其进行解释说明: 功能:     1. ...

  4. CentOS 7 U盘安装问题解决

    最近期待以久的CentOS 7正式版终于发布了,在家里无聊,所以就打算在我的小Y上安装一下,由于笔记本原来有安装Windows 7 操作系统,考虑使用的需求,所以决定安装双系统: 1.         ...

  5. Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

    我在update数据库的时候出现的死锁 数据库表死锁 Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackExcept ...

  6. 第99天:CSS3中透视perspective

    CSS3中透视perspective 透视原理: 近大远小 . 浏览器透视:把近大远小的所有图像,透视在屏幕上. 理解浏览器的坐标系:浏览器平面为 Z=0的平面,坐标原点默认为图片的中心,可以通过更改 ...

  7. mvc4扩展方法

    制作扩展方法,方便网页中使用,下面做了两个例子 using System; using System.Collections.Generic; using System.Linq; using Sys ...

  8. Idea报错Command line is too long

    需要在该项目文件夹下.idea/workspace.xml中添加 <component name="PropertiesComponent"> ... <prop ...

  9. HDU4787_GRE Words Revenge

    这个题目做得泪牛满面. 题目为给你若干串,有的表示添加一个串,有的表示询问一个串有多少个字串为前面出现过的串. 题目一看就知道肯定是AC自动机(不过后缀自动机也是可以的) 但是细想就会发现AC自动机好 ...

  10. bzoj2818 Gcd(欧拉函数)

    Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sam ...