有两种操作,一是给区间内所有的数开根号,二是区间求和。
线段树单点更新,区间求和的模板~
#include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int maxn=1e6+14; struct node { int l; int r; long long sum; }segTree[maxn*4]; long long a[maxn]; void build (int i,int l,int r) { segTree[i].l=l; segTree[i].r=r; if (l==r) { segTree[i].sum=a[l]; return; } int mid=(l+r)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum; } void update (int i,int a,int b) { if (segTree[i].l==a&&segTree[i].r==b&&segTree[i].sum==b-a+1) return; if (segTree[i].l==segTree[i].r) { segTree[i].sum=sqrt(segTree[i].sum); return; } int mid=(segTree[i].l+segTree[i].r)>>1; if (b<=mid) update(i<<1,a,b); else if (a>mid) update(i<<1|1,a,b); else { update(i<<1,a,mid); update(i<<1|1,mid+1,b); } segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum; } long long query (int i,int l,int r) { if (segTree[i].l==l&&segTree[i].r==r) return segTree[i].sum; int mid=(segTree[i].l+segTree[i].r)>>1; if (r<=mid) return query(i<<1,l,r); else if (l>mid) return query(i<<1|1,l,r); else return query(i<<1,l,mid)+query(i<<1|1,mid+1,r); } int main () { int n,m,l,r,flag,cnt=0; while (~scanf("%d",&n)) { cnt++; for (int i=1;i<=n;i++) scanf("%lld",&a[i]); build (1,1,n); scanf ("%d",&m); printf ("Case #%d: ",cnt); for (int i=0;i<m;i++) { scanf ("%d %d %d",&flag,&l,&r); if (l>r) swap(l,r); if (flag==0) update(1,l,r); else printf ("%lld ",query(1,l,r)); } printf (" "); } return 0; }