首页 > 其他分享 >ETT小记

ETT小记

时间:2024-03-04 18:57:08浏览次数:17  
标签:lc ETT ll tag maxn rc define 小记

一个很简单的东西。

题意:一棵树,有点权。多次操作,支持子树加,单点换父亲,查询到根路径权值和。

\(1\le n\le 10^5,\space 1\le m\le 3\times 10^5\)

考虑维护树的欧拉序,就是一个点访问和回溯的时候往后加入序列末尾。

子树加法就是区间加,换父亲就是区间平移,使用平衡树解决,注意一个点的权值带符号。

写了 treap,随机 merge 没过,只好改成随机堆权,发现常数是原来的 \(\dfrac 13\)。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pir pair<ll,ll>
#define fi first
#define se second
#define mkp make_pair
#define pb push_back
using namespace std;
const ll maxn=2e5+10, mod=998244353;
mt19937 rnd(time(0));
struct Treap{
	ll lc[maxn],rc[maxn],val[maxn],sum[maxn],siz[maxn],fa[maxn],tag[maxn],cnt[maxn],ff[maxn],rd[maxn];
	void pushup(ll p){
		sum[p]=sum[lc[p]]+sum[rc[p]]+val[p];
		siz[p]=siz[lc[p]]+siz[rc[p]]+1;
		cnt[p]=cnt[lc[p]]+cnt[rc[p]]+ff[p];
		fa[lc[p]]=fa[rc[p]]=p;
		fa[0]=0;
	}
	void addtag(ll p,ll v){
		if(!p) return;
		val[p]+=v*ff[p], tag[p]+=v, sum[p]+=v*cnt[p];
	}
	void pushdown(ll p){
		if(!tag[p]) return;
		addtag(lc[p],tag[p]), addtag(rc[p],tag[p]);
		tag[p]=0;
	}
	void split(ll p,ll k,ll &x,ll &y){
		if(!p){
			x=y=0; return;
		} pushdown(p);
		if(siz[lc[p]]+1<=k){
			x=p, fa[rc[p]]=0;
			split(rc[p],k-siz[lc[p]]-1,rc[x],y);
			pushup(x);
		} else{
			y=p, fa[lc[p]]=0;
			split(lc[p],k,x,lc[y]);
			pushup(y);
		}
	}
	ll merge(ll p,ll q){
		if(!p||!q) return p|q;
		pushdown(p), pushdown(q);
		if(rd[p]<rd[q]){
			fa[rc[p]]=0;
			rc[p]=merge(rc[p],q);
			pushup(p); return p;
		} else{
			fa[lc[q]]=0;
			lc[q]=merge(p,lc[q]);
			pushup(q); return q;
		}
	}
	void init(ll p,ll v,ll f){
		sum[p]=val[p]=v, cnt[p]=ff[p]=f, tag[p]=lc[p]=rc[p]=fa[p]=0, siz[p]=1;
		rd[p]=rnd()%(1ll<<31);
	}
	ll getrk(ll p){
		ll res=1+siz[lc[p]];
		while(fa[p]){
			if(rc[fa[p]]==p) res+=siz[lc[fa[p]]]+1;
			p=fa[p];
		} return res;
	}
	void renew(ll p){
		if(fa[p]) renew(fa[p]);
		pushdown(p);
	}
	ll query(ll p){
		renew(p);
		ll res=val[p]+sum[lc[p]];
		while(fa[p]){
			if(rc[fa[p]]==p) res+=sum[lc[fa[p]]]+val[fa[p]];
			p=fa[p];
		} return res;
	}
}T;
ll n,a[maxn],m,x,y,rt;
char op[4];
vector<ll>to[maxn];
void dfs(ll u){
	T.init(u,a[u],1);
	rt=T.merge(rt,u);
	for(ll v:to[u]){
		dfs(v);
	}
	T.init(u+n,-a[u],-1);
	rt=T.merge(rt,u+n);
}
ll s1,s2,s3,s;
int main(){
	scanf("%lld",&n);
	for(ll i=2,x;i<=n;i++){
		scanf("%lld",&x); to[x].pb(i);
	}
	for(ll i=1;i<=n;i++) scanf("%lld",a+i);
	dfs(1);
	scanf("%lld",&m);
	T.getrk(16932);
	while(m--){
		scanf("%s%lld",op,&x);
		if(op[0]=='Q') printf("%lld\n",T.query(x));
		else if(op[0]=='C'){ scanf("%lld",&y);
			ll l=T.getrk(x), r=T.getrk(x+n);
			ll t=T.getrk(y);
			T.split(rt,r,s1,s3);
			T.split(s1,l-1,s1,s);
			if(t<l){
				T.split(s1,t,s1,s2); T.fa[s1]=T.fa[s2]=T.fa[s3]=T.fa[s]=0;
				rt=T.merge(T.merge(s1,s),T.merge(s2,s3));
			} else{
				T.split(s3,t-r,s2,s3); T.fa[s1]=T.fa[s2]=T.fa[s3]=T.fa[s]=0;
				rt=T.merge(T.merge(s1,s2),T.merge(s,s3));
			}
		} else{
			scanf("%lld",&y);
			ll l=T.getrk(x), r=T.getrk(x+n);
			T.split(rt,r,s1,s3);
			T.split(s1,l-1,s1,s2);
			T.addtag(s2,y);
			rt=T.merge(T.merge(s1,s2),s3);// T.fa[rt]=0;
		}
	}
	return 0;
}

标签:lc,ETT,ll,tag,maxn,rc,define,小记
From: https://www.cnblogs.com/Sktn0089/p/18052419

相关文章

  • vue3中使用@vue-office/pdf项目中报Cannot set properties of undefined (setting 'wi
    最近项目研发的时候需要使用到pdf预览的功能,规定需要使用@vue-office/pdf插件0.2.5版本号,在使用的时候,一直无法正常运行,错误如下 但是在其他项目中却可以正常使用,想来应该是项目中的某个插件和这个有影响(不兼容)导致pdf无法预览,最终确定是vue版本的问题。正常使用的版本应该为......
  • 单位根反演小记
    核心式子\[[k|n]=\dfrac1k\sum_{i=0}^{k-1}\omega_k^{i\cdotn}\]证明:当\(n\)是\(k\)的因数时,\(\dfrac1k\sum\limits_{i=0}^{k-1}\omega_k^{i\cdotn}=\dfrac1k\sum\limits_{i=0}^{k-1}\omega_k^0=\dfrac1k\cdotk=1\)当\(n\)不是\(k\......
  • 2024考研小记
    距离26日考研成绩公布已经过去了5天,每天会出现很多不同的想法,有时也会怀疑自己要不要继续坚持。想到自己也才稀里糊涂备考了4个月左右,自己取得这样的成绩也是理所应当的。没什么好难过的。随着时间的推移,毕业设计也推上了日程,整个人还是感觉到压力很大,很焦虑。但今天自己还是花......
  • 微信小程序中调用wx.getSetting可以获取到哪些权限设置
    微信小程序中调用wx.getSetting可以获取到哪些权限设置:https://blog.csdn.net/u012767761/article/details/119648707?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170928385316800222888134%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&reque......
  • 数论小记
    gcd辗转相除法,也可以直接用__gcd。线性筛保证每个数只会被其最小的质数筛掉,复杂度\(O(n)\),也可以用来处理积性函数,通常作为更复杂的筛法的预处理。exgcd可用于求解不定方程:\(ax+by=gcd(a,b)\)推导如下:\[ax+by=gcd(a,b)=gcd(b,a\bmodb)=bx'+(a\bmodb)y'......
  • JS/Vue 学习小记
    可能要写点轮子。。。先学学前端知识吧,记录一下。遍历:for(letiofS){i...}for(letiinS){S[i]...}JS是弱类型的语言。目前感觉到的特性有:数组不同元素可以是不同类型的函数返回值不需要声明,直接functionF()就可以JS中对象用大括号表示,成员可以是各种类型,包......
  • Vuex系列之(七)getters配置项
    getters配置项概念:getters配置项并不是必须要使用的,当state中的数据需要经过加工后再使用时,可以使用getters加工。应用场景:运算逻辑复杂而且需要复用,用于抽取基于state中数据的公共运算在store.js中追加getters配置......//准备getters——用于加工state中的数据cons......
  • 易基因:ChIP-seq等揭示FoxO1增加SMC4转录和METTL14介导m6A修饰以促进卵巢癌发展 | 肿瘤
    大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。卵巢癌(Ovariancancer,OC)是影响女性生殖系统的三种常见恶性肿瘤之一。转录因子Forkheadbox蛋白O1(FoxO1),又称forkhead横纹肌肉瘤(rhabdomyosarcoma)转录因子,属于ForkheadboxO(FoxO)转录因子家族,处于肿瘤分子调控网络的中......
  • kettle从入门到精通 第四十九课 ETL之kettle 自定义插件01
    1、kettle插件是什么kettle本身有足够多的转换或者job步骤,但是依然不能覆盖所有的业务场景,所以Kettle自定义插件在有些独特的业务场景可以大显身手。Kettle的插件架构使得我们可以不用修改Kettle本身代码,通过一些独立的代码就可以扩展Kettle的功能。这些独立的代码称为插件。Ke......
  • kettle从入门到精通 第四十八课 ETL之kettle webspoon
    1、kettle自带的客户端spoon工具是cs架构,多人协同办公起来不是特别方便。当然spoon也可以通过文件仓库设置为database模式进行协同办公。每个人在自己电脑上安装&打开spoon客户端,然后设置相同的文件仓库地址。如下图所示。 2、Web-basedSpoon(也称为webSpoon)webSpoon是一个基......