hdu 4027 Can you answer these queries?

暑假集训之后写的第一篇博客。。 开学以来一直在准备网络赛,前几场比赛的还可以,再有10天就现场赛了,感觉时间过的好快,好像还有好多的东西都没接触 呢。 哎,学校条件不够优越,马上要比赛了还要天天上课。 今年尽力吧,争取拿个银奖!! 本题线段树,好长时间都没写过线段树题了,暑假时写过一道,那时写了几个小时没写出来, 之后再碰见线段树题都有点胆怯了,这几天有时间的话再把那题重做一遍。 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 题目大意:给一个长度为n的序列s,有m次询问,每次询问给出三个数,a,b,c, 如果a==1,即输出s[b]+s[b+1]+...+s[c]的和。 如果a==0,即把s[b],s[b+1],...s[c]每个数开方取整! 思路:由于数据量很大,很明显要用到线段树,由于序列中的每个数最大为2^64,经过7,8次开方就变成1了,之后再对1开方就不变了!建立线段树之后 每个叶子节点最多只需要访问8次, 可以给每个节点加一个域,用来判断该节点包含的所有数 是否都已经为1,之后就很容易了! code: # include # include # include //using namespace std; # define N 100005 struct node{ int cp; int l,r; __int64 sum; }tree[8*N]; __int64 a[N],Max; void bulid(int l,int r,int t) { int mid; tree[t].l=l; tree[t].r=r; tree[t].cp=0; if(l==r) { tree[t].sum=a[r]; if(a[r]==1) tree[t].cp=1; return; } mid=(l+r)/2; bulid(l,mid,2*t); bulid(mid+1,r,2*t+1); tree[t].sum=tree[2*t].sum+tree[2*t+1].sum; if(tree[2*t].cp==1 && tree[2*t+1].cp==1) tree[t].cp=1; } void updata(int l,int r,int t) { __int64 ans; if(tree[t].cp==1) return; if(tree[t].l==tree[t].r) { ans=tree[t].sum; ans=(__int64)sqrt((double)ans); if(ans==1) tree[t].cp=1; tree[t].sum=ans; return; } if(r<=tree[2*t].r) updata(l,r,2*t); else if(l>=tree[2*t+1].l) updata(l,r,2*t+1); else { updata(l,tree[2*t].r,2*t); updata(tree[2*t+1].l,r,2*t+1); } tree[t].sum=tree[2*t].sum+tree[2*t+1].sum; if(tree[2*t].cp==1 && tree[2*t+1].cp==1) tree[t].cp=1; } void query(int l,int r,int t) { if(tree[t].l==l && tree[t].r==r) { if(tree[t].cp==1) {Max+=tree[t].sum;return;} else if(tree[t].l==tree[t].r) {Max+=tree[t].sum;return;} } if(r<=tree[2*t].r) query(l,r,2*t); else if(l>=tree[2*t+1].l) query(l,r,2*t+1); else { query(l,tree[2*t].r,2*t); query(tree[2*t+1].l,r,2*t+1); } } int main() { int i,n,Q,ch,from,to,ncase=0,tmp; while(scanf("%d",&n)!=EOF) { ncase++; for(i=1;i<=n;i++) scanf("%I64d",&a[i]); bulid(1,n,1); scanf("%d",&Q); printf("Case #%d:\n",ncase); while(Q--) { scanf("%d%d%d",&ch,&from,&to); if(from>to) {tmp=from;from=to;to=tmp;} if(ch==0) updata(from,to,1); else { Max=0; query(from,to,1); printf("%I64d\n",Max); } } printf("\n"); } return 0; }

你可能感兴趣的:(HDU)