hdu 4027 Can you answer these queries?
2012-11-29 01:12
302 查看
题意:给你N个数,有M个操作,操作有两类,(1)"0 l r",表示将区间[l,r]里的每个数都开根号。(2)"1 l r",表示查询区间[l,r]里所有数的和。
虽然题目给出的数的范围达到了2^63次方,但是,最多开根号7次就会变成1。所以在每次更新的时候,判断,如果这个区间里的所有数被开根号的次数大于7,就不用再往下更新了,其次,因为每个数最多只会有7次开根号,所以在更新的时,可以一直更新到叶子结点。
虽然题目给出的数的范围达到了2^63次方,但是,最多开根号7次就会变成1。所以在每次更新的时候,判断,如果这个区间里的所有数被开根号的次数大于7,就不用再往下更新了,其次,因为每个数最多只会有7次开根号,所以在更新的时,可以一直更新到叶子结点。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(a,b) (a+((b-a)>>1)) const int N=100005; typedef long long LL; struct node { int lft,rht; LL cnt,sum; int mid(){return MID(lft,rht);} int len(){return rht-lft+1;} }; int n,m; LL y ; struct Segtree { node tree[N*4]; void up(int ind) { tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum; if(tree[LL(ind)].cnt>=7&&tree[RR(ind)].cnt>=7) tree[ind].cnt=7; } void build(int lft,int rht,int ind) { tree[ind].lft=lft; tree[ind].rht=rht; tree[ind].cnt=0; tree[ind].sum=0; if(lft==rht) tree[ind].sum=y[lft]; else { int mid=tree[ind].mid(); build(lft,mid,LL(ind)); build(mid+1,rht,RR(ind)); tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum; } } void updata(int st,int ed,int ind) { if(tree[ind].cnt>=7) { tree[ind].sum=tree[ind].len(); return; } int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) { tree[ind].cnt+=1; if(lft==rht) tree[ind].sum=(int)sqrt(tree[ind].sum*1.0); else { updata(st,ed,LL(ind)); updata(st,ed,RR(ind)); up(ind); } } else { int mid=tree[ind].mid(); if(st<=mid) updata(st,ed,LL(ind)); if(ed> mid) updata(st,ed,RR(ind)); up(ind); } } LL query(int st,int ed,int ind) { int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) return tree[ind].sum; else { int mid=tree[ind].mid(); LL sum1=0,sum2=0; if(st<=mid) sum1=query(st,ed,LL(ind)); if(ed> mid) sum2=query(st,ed,RR(ind)); return sum1+sum2; } } }seg; int main() { int t_cnt=0; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%I64d\n",&y[i]); scanf("%d",&m); seg.build(1,n,1); printf("Case #%d:\n",++t_cnt); for(int i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(b>c) swap(b,c); if(a==0) seg.updata(b,c,1); else printf("%I64d\n",seg.query(b,c,1)); } puts(""); } return 0; }
相关文章推荐
- hdu 4027 Can you answer these queries?
- 【HDU】4027 Can you answer these queries?
- hdu 4027 Can you answer these queries?-特殊的单节点更新
- HDU 4027 Can you answer these queries? 线段树,区间修改
- HDU 4027 Can you answer these queries(线段树 成段更新)
- HDU 4027 线段树 Can you answer these queries?
- H - Can you answer these queries? HDU 4027 (线段树+延迟标记+开根号的速度)
- hdu-4027-Can you answer these queries?-线段树
- HDU-4027-Can you answer these queries
- HDU 4027 Can you answer these queries?【线段树+区间更新】
- HDU-4027-Can you answer these queries?(线段树)
- Can you answer these queries? HDU - 4027 线段树单点更新
- HDU 4027 Can you answer these queries?【线段树】区间开平方,区间求和
- HDU 4027 Can you answer these queries?(线段树 区间不等更新)
- HDU 4027 Can you answer these queries?【线段树】
- hdu 4027(线段树)Can you answer these queries?
- HDU 4027 Can you answer these queries?(线段树/区间不等更新)
- HDU 4027 线段树 Can you answer these queries?
- HDU 4027 Can you answer these queries?——其实是点更新的区间更新线段树
- hdu 4027 Can you answer these queries?