• poj3468(一维)(区间查询,区间修改)


    A Simple Problem with Integers

    You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

    Input

    The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
    The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
    Each of the next Q lines represents an operation.
    "C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of AaAa+1, ... , Ab.

    Output

    You need to answer all Q commands in order. One answer in a line.

    Sample Input

    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    

    Sample Output

    4
    55
    9
    15

    Hint

    The sums may exceed the range of 32-bit integers。
     
    还是简单的线段树。
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<cstring>
     6 const int MAXN=100007;
     7 char s[20],c;
     8 long long tree[MAXN*4]={0},add[MAXN*4]={0};
     9 int t,num,x,n,y,m,z,a[MAXN]={0};
    10 using namespace std;
    11 void build(int l,int r,int p){
    12     if (l==r) tree[p]=a[l];
    13     else {
    14         int mid=(l+r)>>1;
    15         build(l,mid,p*2);
    16         build(mid+1,r,p*2+1);
    17         tree[p]=tree[p*2]+tree[p*2+1];
    18     } 
    19 }
    20 long long query(int l,int r,int p,int x,int y){
    21     if (l==x&&r==y) return tree[p]+add[p]*(r-l+1);
    22     else {
    23         add[p*2+1]+=add[p];
    24         add[p*2]+=add[p];
    25         tree[p]+=add[p]*(r-l+1);
    26         add[p]=0;
    27         int mid=(l+r)>>1;
    28         if (y<=mid) return query(l,mid,p*2,x,y);    
    29         else if(x>=mid+1) return query(mid+1,r,p*2+1,x,y); 
    30              else return query(l,mid,p*2,x,mid)+query(mid+1,r,p*2+1,mid+1,y);
    31     }
    32 }
    33 void change(int l,int r,int p,int x,int y,int zhi)
    34 {
    35     if (l==x&&r==y) add[p]+=zhi;
    36     else
    37     {
    38         tree[p]+=zhi*(y-x+1);
    39         int mid=(l+r)>>1;
    40         if (y<=mid) change(l,mid,p*2,x,y,zhi);
    41         else if (x>mid) change(mid+1,r,p*2+1,x,y,zhi);
    42         else
    43         {
    44             change(l,mid,p*2,x,mid,zhi);
    45             change(mid+1,r,p*2+1,mid+1,y,zhi);
    46         }
    47     }
    48 }
    49 int main(){
    50     while (~scanf("%d%d",&n,&m)){
    51         for (int i=1;i<=n;i++)
    52             scanf("%d",&a[i]);        
    53         build(1,n,1);
    54         for (int i=1;i<=m;i++){
    55             scanf("%s%d%d",&s,&x,&y);
    56             if (s[0]=='Q') printf("%lld
    ",query(1,n,1,x,y));
    57             else {
    58                 scanf("%d",&z);
    59                 change(1,n,1,x,y,z);
    60             }
    61         }
    62     }
    63 }

     线段树虽然简单,但是树状数组就没有这么简单了,差分思想。

    转换应该在树状数组blog上已经讲过了,会在blog上持续更新,最新的理解。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 #define N 100007
     7 using namespace std;
     8 
     9 int n,m;
    10 long long c[N],d[N];
    11 char ch[3];
    12 
    13 int lowbit(int x)
    14 {
    15     return x&(-x);
    16 }
    17 void change(int x,int y,int z)
    18 {
    19     for (int i=x;i<=n;i+=lowbit(i))
    20         c[i]+=z;
    21     for (int i=y+1;i<=n;i+=lowbit(i))
    22         c[i]-=z;
    23         
    24     for (int i=x;i<=n;i+=lowbit(i))
    25         d[i]+=(long long)z*x;
    26     for (int i=y+1;i<=n;i+=lowbit(i))
    27         d[i]-=(long long)z*(y+1);            
    28 }
    29 long long query(int x)
    30 {
    31     long long res=0,ans=0;
    32     for (int i=x;i>=1;i-=lowbit(i))
    33         res+=c[i];
    34     ans+=res*(x+1);
    35     res=0;
    36     for (int i=x;i>=1;i-=lowbit(i))
    37         res+=d[i];
    38     ans-=res;
    39     return ans;        
    40 }
    41 int main()
    42 {
    43     scanf("%d%d",&n,&m);
    44     int last=0,x,y,z;
    45     for (int i=1;i<=n;i++)
    46     {
    47         scanf("%d",&x);
    48         y=x-last;
    49         change(i,n,y);
    50         last=x;
    51     }
    52     for (int i=1;i<=m;i++)
    53     {
    54         scanf("%s",ch);
    55         if (ch[0]=='Q')
    56         {
    57             scanf("%d%d",&x,&y);
    58             printf("%lld
    ",query(y)-query(x-1));
    59         }
    60         else
    61         {
    62             scanf("%d%d%d",&x,&y,&z);
    63             change(x,y,z);
    64         }
    65     }
    66 }
  • 相关阅读:
    Ubuntu中安装XAMPP出错的解决方法
    sudo 后不用输入密码的配置
    javascript鼠标双击时触发事件大全
    PHP空值判断
    40音乐海报的创意例子
    35个令人印象深刻的创意404错误页面设计
    35个高分辨率创意苹果桌面壁纸
    38惊人的HD(高清晰度)壁纸七彩的例子
    25精心设计的联系页面例子
    pgpoolII中对 setsockopt 的利用
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7535343.html
Copyright © 2020-2023  润新知