HDU1698(遞迴建立線段樹)
阿新 • • 發佈:2018-12-09
遞迴方法建立線段樹,通過時間是686ms,可能有更快的方法,需要繼續學習!
下面是AC程式碼:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn=100000+10; int n,m,L,R,C; int tree[maxn<<2]; int add[maxn<<2]; void pushup(int rt) { tree[rt]=tree[rt<<1]+tree[rt<<1|1]; } void build_tree(int l,int r,int rt) { if(l==r) { tree[rt]=1; return; } int m=(l+r)>>1; build_tree(l,m,rt<<1); build_tree(m+1,r,rt<<1|1); pushup(rt); } void pushdown(int ln,int rn,int rt) { if(add[rt]) { add[rt<<1]=add[rt]; add[rt<<1|1]=add[rt]; tree[rt<<1]=add[rt]*ln; tree[rt<<1|1]=add[rt]*rn; add[rt]=0; } } void update(int l,int r,int rt) { if(L<=l&&r<=R) { tree[rt]=(r-l+1)*C; add[rt]=C; return; } int m=(l+r)>>1; pushdown(m-l+1,r-m,rt); if(L<=m) update(l,m,rt<<1); if(m<R) update(m+1,r,rt<<1|1); pushup(rt); } int query(int l,int r,int rt) { if(L<=l&&r<=R) { ///printf("底層值為%d\n",tree[rt]); return tree[rt]; } int m=(l+r)>>1; pushdown(m-l+1,r-m,rt); int ans=0; if(L<=m) ans+=query(l,m,rt<<1); if(m<R) ans+=query(m+1,r,rt<<1|1); ///printf("返回值為%d\n",ans); return ans; } int main() { int t,T; scanf("%d",&t); T=t; while(t--) { scanf("%d%d",&n,&m); memset(add,0,sizeof(add)); build_tree(1,n,1); for(int i=0; i<m; i++) { scanf("%d%d%d",&L,&R,&C); update(1,n,1); } L=1; R=n; printf("Case %d: The total value of the hook is %d.\n",T-t,query(1,n,1)); } return 0; }