首页 > 其他分享 >CF396C On Changing Tree

CF396C On Changing Tree

时间:2024-02-17 23:11:58浏览次数:29  
标签:tag1 int ll Tree dep maxn CF396C Changing now

看到距离有关可以联想到跟深度有关系,可以用深度表示距离关系。
假设现在有一操作1 v x k,那么对于v下一点u,设dep[v]为v的深度,那么两点间距离就是dep[u]-dep[v],于是u点就会增加\(x-k*(dep[u]-dep[v])=x-k*dep[u]+k*dep[v]\)。
由此来看,只需要把v一下的\(sum1\)都加上\(x-dep[u]\),然后再对u点再查询时单独加回一个\(k*dep[v]\),对于多个操作就加回k的和乘上\(dep[v]\)。
为了维护k的和,可以设\(sum2\),在操作时把v以下的\(sum2\)都加上\(k\)。
对一个子树进行操作,由于只对根操作,故直接dfs序即可。

代码

#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
#define maxn 300005
#define ll long long
using namespace std;
int n;
int head[maxn],to[maxn*2],nex[maxn*2],m1;
void add(int u,int v) {
	to[++m1]=v;
	nex[m1]=head[u];
	head[u]=m1;
}
int lf[maxn],rt[maxn],dfn[maxn];
ll dep[maxn],num;
void dfs(int now,int last) {
	lf[now]=++num,dfn[num]=now,dep[now]=dep[last]+1;
	for(int i=head[now];i;i=nex[i]) {
		int st=to[i];
		dfs(st,now);
	}
	rt[now]=num;
}
struct smt {
	int l,r;
	ll tag1,tag2;
} T[maxn*4];
int ls(int x) {return x<<1;}
int rs(int x) {return x<<1|1;}
ll mod=1e9+7;
void tree_pre(int x,int l,int r) {
	T[x].l=l,T[x].r=r;
	if(l==r) return;
	int mid=(l+r)>>1;
	tree_pre(ls(x),l,mid);
	tree_pre(rs(x),mid+1,r);
}
void change(int x,ll val1,ll val2) {
	T[x].tag1=(T[x].tag1+val1)%mod;
	T[x].tag2=(T[x].tag2+val2)%mod;	
}
void push_down(int x) {
	change(ls(x),T[x].tag1,T[x].tag2);
	change(rs(x),T[x].tag1,T[x].tag2);
	T[x].tag1=T[x].tag2=0;
}
void modify(int x,int l,int r,ll val1,ll val2) {
	if(T[x].l>=l && T[x].r<=r) {
		change(x,val1,val2);
		return;
	}
	push_down(x);
	if(T[ls(x)].r>=l) modify(ls(x),l,r,val1,val2);
	if(T[rs(x)].l<=r) modify(rs(x),l,r,val1,val2);
}
ll query(int x,int l,int r) {
	if(T[x].l>=l && T[x].r<=r) return (T[x].tag1-dep[dfn[l]]*T[x].tag2%mod+mod)%mod;
	push_down(x);
	if(T[ls(x)].r>=l) return query(ls(x),l,r);
	if(T[rs(x)].l<=r) return query(rs(x),l,r);
}
int main() {
//	freopen("CF396C.in","r",stdin);
//	freopen("CF396C.out","w",stdout);
	scanf("%d",&n);
	for(int i=2;i<=n;i++) {
		int x; scanf("%d",&x);
		add(x,i);
	}
	dfs(1,0);
	tree_pre(1,1,n);
	int q; scanf("%d",&q);
	for(int i=1;i<=q;i++) {
		int t;
		ll v,x,k;
		scanf("%d",&t);
		if(t==1) {
			scanf("%lld%lld%lld",&v,&x,&k);
			ll val1=(x+dep[v]*k%mod)%mod,val2=k;
			modify(1,lf[v],rt[v],val1,val2);
		}
		else {
			scanf("%lld",&v);
			printf("%lld\n",query(1,lf[v],lf[v]));
		}
	}
	return 0;
}

标签:tag1,int,ll,Tree,dep,maxn,CF396C,Changing,now
From: https://www.cnblogs.com/1n87/p/18018603

相关文章

  • [ARC108F] Paint Tree
    本题有两种思路。首先,对于普通的树,到一个点最远的点一定是直径的端点之一。记\(S\)表示直径长度。做法\(1\)先求出一条直径,若直径的两个端点颜色相同,则最长距离一定为直径。否则,令两个端点分别为\(x,y\),并钦定\(x,y\)不同色。枚举答案\(d\),所有到\(x\)距离\(>d\)的......
  • TreeMap排序
    实现TreeMap后默认为key升序排序,如果要实现key其他排序规则,可以使用Comparator对象作为参数,前提是key为可以排序的类型(String,int等类型)1Map<String,People>map=newTreeMap<>(newComparator<String>(){2@Override3publicintcompare(finalStringo1,final......
  • Check if a given binary tree is BST【2月14日学习笔记】
    点击查看代码//CheckifagivenbinarytreeisBST#include<iostream>#defineMIN-999999#defineMAX999999structnode{intdata;node*left;node*right;};node*getnewnode(intx){node*temp=newnode;temp->data=x;......
  • JDK21报错 java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTre
    JDK21报错java:java.lang.NoSuchFieldError:Classcom.sun.tools.javac.tree.JCTree$JCImportdoesnothavememberfield'com.sun.tools.javac.tree.JCTreequalid'Lombok版本兼容性的问题导致Maven依赖改为新版本<dependency><groupId>org.projectlombok&l......
  • 迎龙年浅谈 Binary Indexed Trees
    什么是BinaryIndexedTrees?就是树状数组啦。树状数组,是一种高级数据结构,用于高效地解决某一类问题。那么这一类问题是什么呢?那么让我们一起来看一下:问题引入给定一个序列\(a\),给定\(Q\)个\(l,r\),求\(\sum_{i=l}^ra_i\)。这一类问题,我们明显可以暴力枚举,时间复杂度为......
  • CF1918F Caterpillar on a Tree
    题意简述你想要遍历一棵大小为\(n\)的树,初始在根节点\(1\),每次你可以花费\(1\)从一个点通过一条边到达另一个点,或者花费\(0\)传送到根节点。求完成遍历的最小代价。\(n\le2\times10^5,k\le10^9\)。分析首先,传送门肯定是在叶子节点使用。其次,遍历顺序是按照子树的深......
  • Link Cut Tree模板(从别人那里拿的)
    可以通过这道题#include<bits/stdc++.h>#defineRregisterint#defineIinlinevoid#defineGif(++ip==ie)if(fread(ip=buf,1,SZ,stdin))#definelcc[x][0]#definercc[x][1]usingnamespacestd;constintSZ=1<<19,N=3e5+9;charbuf[SZ],*ie=buf+SZ,*ip=......
  • P9663 Permutation on Tree 题解
    考虑枚举一个\(x\in[1,n)\),将\(\leqx\)的看作\(0\),\(>x\)的看作\(1\),那么一个排列的贡献实际上就是\(\sum_{x=1}^{n-1}\sum[[p_i\leqx]+[p_{i+1}>x]=1]\)。那么问题转变为一个给定一棵树,每一个点有权值\(0\)或\(1\),求所有排布方案的贡献之和。设\(f_x\)表示......
  • P10013 Tree Topological Order Counting 题解
    首先题目里面写了每一个数都有权值,一般这种题只能去想求出每一个的具体方案数,那么也就是我们得求出\(h_{i,j}\)表示在所有合法拓扑序中\(a_i=j\)的方案数。一颗树的拓扑序数量是\(\dfrac{n!}{\prodsiz_i}\),相信大家都知道。因为我们需要保证这一棵树满足拓扑排序的条件,不......
  • element-plus 2.4.1版本 el-tree踩坑
    element-plus2.4.1版本el-tree设置属性props中的label时,无法指定,例如<el-tree:data="datas.tree_data"show-checkboxnode-key="menu_id":props="{//label:function(data,node){//returndata.menu_name;//},......