标签:
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4027
线段树功能:区间修改,区间求和。
分析:因为每个数至多开6次平方就变1了,所以对于每一段全为1的线段做lazy标志,若该条线段全为1时,就不用继续往下update,修改复杂度O(6*N),查询O(logN)。
#pragma comment(linker,"/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <cstdlib> #include <stack> #include <vector> #include <set> #include <map> #define LL long long #define mod 1000000007 #define inf 0x3f3f3f3f #define N 100010 #define FILL(a,b) (memset(a,b,sizeof(a))) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; LL sum[N<<2],col[N<<2],a[N]; void Pushup(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; col[rt]=col[rt<<1]&&col[rt<<1|1]; } void build(int l,int r,int rt) { col[rt]=0; if(l==r) { sum[rt]=a[l]; return; } int m=(l+r)>>1; build(lson); build(rson); Pushup(rt); } void update(int L,int R,int l,int r,int rt) { if(l==r) { sum[rt]=(LL)sqrt(sum[rt]); if(sum[rt]==1)col[rt]=1; return; } int m=(l+r)>>1; if(L<=m&&!col[rt<<1])update(L,R,lson); if(m<R&&!col[rt<<1|1])update(L,R,rson); Pushup(rt); } LL query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return sum[rt]; int m=(l+r)>>1; LL res=0; if(L<=m)res+=query(L,R,lson); if(m<R)res+=query(L,R,rson); return res; } int main() { int n,m,cas=1; while(scanf("%d",&n)>0) { for(int i=1;i<=n;i++)scanf("%I64d",&a[i]); build(1,n,1); scanf("%d",&m); printf("Case #%d:\n",cas++); while(m--) { int op,x,y; scanf("%d%d%d",&op,&x,&y); if(x>y)swap(x,y); if(op==0) { update(x,y,1,n,1); } else { LL res=query(x,y,1,n,1); printf("%I64d\n",res); } } puts(""); } }
标签:
原文地址:http://www.cnblogs.com/lienus/p/4240366.html