Codeforces Round #179 (Div. 1) A題 線段樹
阿新 • • 發佈:2018-12-24
有m個操作,每個操作給出l,r,d值,表示從a(l)到a(r)區間內的每個值加d。
接下來k個範圍,每個範圍為x到y,表示從第x個操作到第y個操作都執行一次。
輸出最後得到的陣列a。
兩次線段樹,第一次求出每種操作各需要多少次,第二次根據第一次結果求出最終結果。
程式碼如下
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #define INF 200000000 #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define maxm 200005 __int64 time[maxm<<2],lazy1[maxm<<2],cover[maxm<<2],lazy2[maxm<<2],a[maxm+5],op[maxm+5][3]; void pushdown1(__int64 rt) { time[rt]+=lazy1[rt]; lazy1[rt<<1]+=lazy1[rt]; lazy1[rt<<1|1]+=lazy1[rt]; lazy1[rt]=0; } void build1(__int64 l,__int64 r,__int64 rt) { __int64 mid; time[rt]=0; lazy1[rt]=0; if(r>l) { mid=(l+r)>>1; build1(lson); build1(rson); } } void update1(__int64 L,__int64 R,__int64 l,__int64 r,__int64 rt) { __int64 mid; if(L<=l&&r<=R) { lazy1[rt]++; return ; } pushdown1(rt); if(r>l) { mid=(l+r)>>1; if(L<=mid) update1(L,R,lson); if(R>mid) update1(L,R,rson); } } __int64 search1(__int64 d,__int64 l,__int64 r,__int64 rt) { __int64 mid; pushdown1(rt); if(l==r) { return time[rt]; } mid=(l+r)>>1; if(d<=mid) return search1(d,lson); else return search1(d,rson); } void build2(__int64 l,__int64 r,__int64 rt) { __int64 mid; cover[rt]=0; lazy2[rt]=0; if(r>l) { mid=(l+r)>>1; build2(lson); build2(rson); } } void pushdown2(__int64 rt) { cover[rt]+=lazy2[rt]; lazy2[rt<<1]+=lazy2[rt]; lazy2[rt<<1|1]+=lazy2[rt]; lazy2[rt]=0; } void update2(__int64 L,__int64 R,__int64 c,__int64 l,__int64 r,__int64 rt) { __int64 mid; if(L<=l&&r<=R) { lazy2[rt]+=c; return ; } pushdown2(rt); if(r>l) { mid=(l+r)>>1; if(L<=mid)update2(L,R,c,lson); if(R>mid)update2(L,R,c,rson); } } __int64 search2(__int64 d,__int64 l,__int64 r,__int64 rt) { __int64 mid; pushdown2(rt); if(l==r) return cover[rt]; mid=(l+r)>>1; if(d<=mid) return search2(d,lson); else return search2(d,rson); } int main() { __int64 i,j,k,l,n,m,kk,le,ri; while(scanf("%I64d%I64d%I64d",&n,&m,&kk)!=EOF) { for(i=1;i<=n;i++) scanf("%I64d",&a[i]); for(i=1;i<=m;i++) scanf("%I64d%I64d%I64d",&op[i][0],&op[i][1],&op[i][2]); build1(1,m,1); for(i=1;i<=kk;i++) { scanf("%I64d%I64d",&le,&ri); update1(le,ri,1,m,1); } build2(1,n,1); for(i=1;i<=m;i++) { j=op[i][2]; k=search1(i,1,m,1); update2(op[i][0],op[i][1],j*k,1,n,1); } for(i=1;i<n;i++) printf("%I64d ",a[i]+search2(i,1,n,1)); printf("%I64d\n",a[i]+search2(i,1,n,1)); } return 0; }