hdu3468 splay
来源:互联网 发布:知乎体格式 编辑:程序博客网 时间:2024/06/10 08:22
题意:其实就是区间的加法和询问区间的和
解法:主要为了尝试一下splay维护区间和 因为之前只写过splay区间加法维护
然后觉得很神奇啊 左右两个节点是不算内的,以前写单点都没有发现这一点吧
#include<cstdio>#include<iostream>using namespace std;typedef long long ll;#define ls ch[rt][0]#define rs ch[rt][1]#define rrs ch[root][1]#define rls ch[root][0]#define maxn 222222int n,m;int ch[maxn][2],fa[maxn],root,num[maxn],cnt;ll sum[maxn],add[maxn],a[maxn],val[maxn];inline void node(int rt){fa[rt]=sum[rt]=add[rt]=ls=rs=0;num[rt]=1;}inline void up(int rt){ sum[rt]=val[rt]+sum[ls]+sum[rs]; num[rt]=num[ls]+num[rs]+1;}inline void down(int rt){ if(add[rt]){ if(ls)add[ls]+=add[rt],val[ls]+=add[rt],sum[ls]+=add[rt]*(num[ls]); if(rs)add[rs]+=add[rt],val[rs]+=add[rt],sum[rs]+=add[rt]*(num[rs]); add[rt]=0; }}inline void rot(int rt){ int f=fa[rt],side=ch[f][1]==rt,ll=ch[rt][!side]; fa[ll]=f,ch[f][side]=ll; fa[rt]=fa[f],ch[fa[f]][ch[fa[f]][1]==f]=rt; fa[f]=rt,ch[rt][!side]=f; up(f),up(rt);}void splay(int rt,int aim){ while(fa[rt]!=aim){ down(rt); int f=fa[rt],ff=fa[f]; if(ff==aim)rot(rt); else if((ch[f][1]==rt)==(ch[ff][1]==f))rot(f),rot(rt); else rot(rt),rot(rt); }if(!aim)root=rt;}inline void find(int tot,int sub){ int rt=sub; while(1){ down(rt); if(num[ls]+1==tot)break; if(num[ls]>=tot)rt=ls; else tot-=num[ls]+1,rt=rs; }splay(rt,fa[sub]);}void _add(int l,int r,ll w){ find(l,root);find(r-l+2,rrs); int rt=ch[rrs][0]; sum[rt]+=w*num[rt];add[rt]+=w;val[rt]+=w;}void build(int n){ cnt=0;node(0);num[0]=0; node(++cnt); for(int i=2;i<=n+1;++i){ node(++cnt);fa[i-1]=i;ch[i][0]=i-1;val[i]=a[i];up(i); }root=cnt; node(++cnt);fa[cnt]=cnt-1;ch[cnt-1][1]=cnt;up(root);// for(int i=1;i<=n+2;++i)// printf("%d %d %d %lld\n",i,fa[i],num[i],sum[i]); }char op[111];int l,r;int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=2;i<=n+1;++i)scanf("%lld",&a[i]); build(n); while(m--){ scanf("%s%d%d",op,&l,&r); if(*op=='Q'){ find(l,root);find(r-l+2,rrs);// printf("%lld %lld\n",val[root],val[rrs]); printf("%lld\n",sum[ch[rrs][0]]); }else if(*op=='C'){ ll w;scanf("%lld",&w); _add(l,r,w); } } } return 0;}
0 0
- hdu3468 splay
- hdu3468 Treasure Hunting 二分匹配
- SPLAY
- splay
- splay
- splay
- Splay
- Splay
- splay
- splay
- splay
- splay
- Splay
- splay
- Splay
- splay
- Splay
- Splay
- GPU并行编程方法
- SQLAlchemy实战详解
- SQL点滴26—常见T-SQL面试解析
- Add Binary
- Android service详解(一)
- hdu3468 splay
- mongoVUE 数据的json格式导入导出
- zoj 2158 Truck History(最小生成树))
- 为什么采用Always On SSL?
- 揭开Socket编程的面纱
- C/C++面试编程题
- 【刷题小记97】兄弟郊游问题
- SQL点滴30—SQL中常用的函数
- 在线音乐歌词实现方式