线段树动态开点区间加区间求和
生活随笔
收集整理的這篇文章主要介紹了
线段树动态开点区间加区间求和
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
線段樹動態(tài)開點區(qū)間加區(qū)間求和
題目來源:
陜西師范大學第七屆程序設計競賽網絡同步賽 H. 萬惡的柯怡
思想:
保證葉子節(jié)點被完整的覆蓋,需要開節(jié)點,就把左右兒子都開出來,其余和普通線段樹一樣。
tips:
用結構體內部函數,內存不足,(第一次遇見本地問題不嚴重)不明嚼栗???
模板:
#include <bits/stdc++.h> typedef long long ll; const int N = 4000010; using namespace std; struct node{ll sum,tag;int lson,rson; // node(){}node(ll c,ll d,int e,int f){ ***memory limit error*** // sum=c;tag=d;lson=e;rson=f; // } }T[N]; int cnt; void newnode(int &x,ll sum) {x = ++cnt;T[x].sum = sum;T[x].lson = T[x].rson = -1;T[x].tag = 0; } void push_down(int p,ll l,ll r) {ll mid = (l+r) >> 1LL;if(T[p].tag) {if(T[p].lson==-1&&T[p].rson==-1){newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));T[T[p].lson].tag += T[p].tag;T[T[p].rson].tag += T[p].tag;}else {T[T[p].lson].tag += T[p].tag;T[T[p].rson].tag += T[p].tag;T[T[p].lson].sum += T[p].tag*(mid-l+1LL);T[T[p].rson].sum += T[p].tag*(r-mid);}T[p].tag = 0;} } ll ask(int p,ll L,ll R,ll l,ll r) {if(L<=l&&r<=R) return T[p].sum;push_down(p,l,r);ll mid = (l+r)>>1LL;if(mid>=R) {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));return ask(T[p].lson,L,R,l,mid);}else if(mid < L) {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));return ask(T[p].rson,L,R,mid+1LL,r);}else {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));return ask(T[p].lson,L,mid,l,mid)+ask(T[p].rson,mid+1LL,R,mid+1LL,r);} } void push_up(int p) {T[p].sum = (T[p].lson!=-1)*T[T[p].lson].sum + (T[p].rson!=-1)*T[T[p].rson].sum; }void add(int p,ll L,ll R,ll l,ll r,ll x) {if(L<=l&&r<=R) {T[p].tag += x;T[p].sum += (r-l+1LL)*x;return;}push_down(p,l,r);ll mid = (l+r)>>1LL;if(mid>=R) {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));add(T[p].lson,L,R,l,mid,x);}else if(mid < L) {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));add(T[p].rson,L,R,mid+1LL,r,x);}else {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));add(T[p].lson,L,mid,l,mid,x),add(T[p].rson,mid+1LL,R,mid+1LL,r,x);}push_up(p); }int main() {int q;scanf("%d",&q);cnt = 0;int rt = ++cnt;int K=0;ll res = 0;T[rt].sum = 0;T[rt].lson=T[rt].rson = -1;T[rt].tag = 0;while(q--) {int opt;ll L,R,x;scanf("%d",&opt);if(opt) {scanf("%lld%lld",&L,&R);printf("%lld\n",ask(rt,L,R,0,1000000000LL));}else {scanf("%lld%lld%lld",&L,&R,&x);add(rt,L,R,0,1000000000LL,x);}}return 0; }H. 萬惡的柯怡
#include <bits/stdc++.h> typedef long long ll; const int N = 4000010; using namespace std; struct node{ll sum,tag;int lson,rson; }T[N]; int cnt; void newnode(int &x,ll sum) {x = ++cnt;T[x].sum = sum;T[x].lson = T[x].rson = -1;T[x].tag = 0; } void push_down(int p,ll l,ll r) {ll mid = (l+r) >> 1LL;if(T[p].tag) {if(T[p].lson==-1&&T[p].rson==-1){newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));T[T[p].lson].tag += T[p].tag;T[T[p].rson].tag += T[p].tag;}else {T[T[p].lson].tag += T[p].tag;T[T[p].rson].tag += T[p].tag;T[T[p].lson].sum += T[p].tag*(mid-l+1LL);T[T[p].rson].sum += T[p].tag*(r-mid);}T[p].tag = 0;} } ll ask(int p,ll L,ll R,ll l,ll r) {if(L<=l&&r<=R) return T[p].sum;push_down(p,l,r);ll mid = (l+r)>>1LL;if(mid>=R) {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));return ask(T[p].lson,L,R,l,mid);}else if(mid < L) {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));return ask(T[p].rson,L,R,mid+1LL,r);}else {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));return ask(T[p].lson,L,mid,l,mid)+ask(T[p].rson,mid+1LL,R,mid+1LL,r);} } void push_up(int p) {T[p].sum = (T[p].lson!=-1)*T[T[p].lson].sum + (T[p].rson!=-1)*T[T[p].rson].sum; }void add(int p,ll L,ll R,ll l,ll r,ll x) {if(L<=l&&r<=R) {T[p].tag += x;T[p].sum += (r-l+1LL)*x;return;}push_down(p,l,r);ll mid = (l+r)>>1LL;if(mid>=R) {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));add(T[p].lson,L,R,l,mid,x);}else if(mid < L) {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));add(T[p].rson,L,R,mid+1LL,r,x);}else {if(T[p].lson==-1) newnode(T[p].lson,T[p].sum/(r-l+1LL)*(mid-l+1LL));if(T[p].rson==-1) newnode(T[p].rson,T[p].sum/(r-l+1LL)*(r-mid));add(T[p].lson,L,mid,l,mid,x),add(T[p].rson,mid+1LL,R,mid+1LL,r,x);}push_up(p); }int main() {int TT;scanf("%d",&TT);while(TT--) {int q;scanf("%d",&q);cnt = 0;int rt = ++cnt;int K=0;ll res = 0;T[rt].sum = 0;T[rt].lson=T[rt].rson = -1;T[rt].tag = 0;while(q--) {ll l,r,keyiL,keyiR,x;scanf("%lld %lld %lld %lld %lld",&l,&r,&x,&keyiL,&keyiR);l=l^res;r=r^res;keyiL=keyiL^res;keyiR=keyiR^res;if(l>r)swap(l,r);if(keyiL>keyiR)swap(keyiL,keyiR);add(rt,l,r,0,1000000000,x);res = ask(rt,keyiL,keyiR,0,1000000000);printf("%lld\n",res);res %= 19980105;}}return 0; }轉載于:https://www.cnblogs.com/RRRR-wys/p/9324745.html
總結
以上是生活随笔為你收集整理的线段树动态开点区间加区间求和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习笔记(二十八):高斯核函数
- 下一篇: Codeforces Round #49