poj 3468 题意就是区间修改和区间求和。
开始没考虑如对1-10这个区间只更新了1-5,求和1-10的时候没加这个更新,应该结构上加上个b。
#include<iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <map> #include <set> #include <algorithm> using namespace std; const int maxn=100000+7; struct ttt{ long long l,r,w,a,b; }; long long qq[maxn]; ttt tree[4*maxn]; int build(long long l,long long r,int num){ tree[num].l=l; tree[num].r=r; if(l==r){ tree[num].w=qq[l];return 0; } build(l,(l+r)/2,num+num); build((l+r)/2+1,r,num+num+1); tree[num].w=tree[num+num].w+tree[num+num+1].w; } int update(long long l,long long r,long long y,int num){ if(tree[num].l>=l&&tree[num].r<=r){ //区间属于l,r tree[num].a+=y; return 0; } tree[num].b+=y*(min(r,tree[num].r)-max(l,tree[num].l)+1);//考虑这个区间只加部分,但是选这个区间 //得考虑这部分和也得选上 int mid1=(tree[num].l+tree[num].r)/2; if(l>mid1){ update(l,r,y,num+num+1); }else if(r<=mid1){ update(l,r,y,num+num); }else if(l<=mid1&&r>mid1){ update(l,r,y,num+num); update(l,r,y,num+num+1); } } long long sum1; int find1(long long l,long long r,int num){ if(l<=tree[num].l&&r>=tree[num].r){ //区间属于l,r sum1+=tree[num].w+tree[num].a*(tree[num].r-tree[num].l+1); sum1+=tree[num].b; }else{ sum1+=tree[num].a*(min(r,tree[num].r)-max(l,tree[num].l)+1); //l,r在这个区间的值 int mid1=(tree[num].l+tree[num].r)/2; if(l>mid1){ find1(l,r,num+num+1); }else if(r<=mid1){ find1(l,r,num+num); }else if(l<=mid1&&r>mid1){ find1(l,r,num+num); find1(l,r,num+num+1); } } } int main(){ long long i,j,k,f1,f2,f3,f4,t1,t2,t3,t4,n,m; //reopen("in.txt","r",stdin); memset(tree,0,sizeof(tree)); cin >> n >> m; t3=0; for(i=1;i<=n;i++){ scanf("%lld",&qq[i]); } scanf("\n"); char b; build(1,n,1); for(i=1;i<=m;i++){ scanf("%c %lld %lld",&b,&t1,&t2); if(b=='Q'){ scanf("\n"); sum1=0; find1(t1,t2,1); printf("%lld\n",sum1); }else{ scanf("%lld\n",&t3); update(t1,t2,t3,1); } } return 0; }树状数组也能区间更新和查找,速度会更快一些,开的数组就是n的大小。
#include <iostream> #include <stdio.h> #include <string.h> #include <stack> #include <vector> #include <algorithm> #include <set> using namespace std; const int maxn=1e6+7; typedef long long ll; ll n,c1[maxn],c2[maxn]; ll lowbits(ll x){ return x&(-x);} void add(ll *r,ll pos,ll v){ while(pos<=n){ r[pos]+=v; pos+=lowbits(pos); } } ll sigma(ll *r,ll pos){ ll anx=0; while(pos>0){ anx+=r[pos]; pos-=lowbits(pos); } return anx; } int main(){ //freopen("in.txt","r",stdin); long long i,j,k,f1,f2,f3,t1,t2,t3,sum1,sum2; int m; cin >> n>>m; for(i=1;i<=n;i++){ scanf("%lld",&f3); f1=f2=i; add(c1,f1,f3);add(c1,f2+1,-f3); add(c2,f1,f3*(f1-1));add(c2,f2+1,-f3*f2); } char b; scanf("\n"); while(m--){ scanf("%c %lld %lld",&b,&f1,&f2); if(b=='C'){ //t2==1时候,f1-f2加f3 scanf("%lld\n",&f3); add(c1,f1,f3);add(c1,f2+1,-f3); add(c2,f1,f3*(f1-1));add(c2,f2+1,-f3*f2); }else{ //t2==2 的时候 查询f1-f2的和 scanf("\n"); sum1=(f1-1)*sigma(c1,f1-1)-sigma(c2,f1-1); sum2=f2*sigma(c1,f2)-sigma(c2,f2); cout << sum2-sum1 << endl; } } return 0; }