zoukankan      html  css  js  c++  java
  • codevs1082

    题目描述 Description

    给你N个数,有两种操作:
    1:给区间[a,b]的所有数增加X
    2:询问区间[a,b]的数的和。

    输入描述 Input Description

    第一行一个正整数n,接下来n行n个整数,

    再接下来一个正整数Q,每行表示操作的个数,

    如果第一个数是1,后接3个正整数,

    表示在区间[a,b]内每个数增加X,如果是2,

    表示操作2询问区间[a,b]的和是多少。

    输出描述 Output Description

    对于每个询问输出一行一个答案

    样例输入 Sample Input

    3

    1

    2

    3

    2

    1 2 3 2

    2 2 3

    样例输出 Sample Output

    9

    数据范围及提示 Data Size & Hint

    数据范围

    1<=n<=200000

    1<=q<=200000

     

    先给出最基础的线段树的打法

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    int n,Q,a[200005];
    
    inline int read(){
        char ch=getchar();int k=0,f=1;
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)){k=(k<<1)+(k<<3)+ch-'0';ch=getchar();}
        return k*f;
    }
    
    void add(int x,int add){
        for(;x<=n;x+=x&-x) a[x]+=add;
    }
    
    int query(int x){
        int k=0;for(;x;x-=x&-x) k+=a[x];return k; 
    }
    
    int main(){
        n=read();
        for(int i=1;i<=n;i++) add(i,read());
        Q=read();
        for(int i=1;i<=Q;i++){
            int flag=read(),x=read(),y=read();if(x>y)swap(x,y);
            if(flag==1){
                int z=read();
                add(x,(y-x+1)*z);add(y+1,-(y-x+1)*z);
            }
            else printf("%ld\n",query(y)-query(x-1));
        }
        return 0;
    }

    但打这题主要是为了理解树状数组的区间修改和区间查询

    #include<cstdio>
    #include<cctype>
    using namespace std;
    
    long long c1[200004],c2[200004],n,q;
    
    inline long long read(){
        char ch=getchar();long long k=0;
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)){k=(k<<1)+(k<<3)+ch-'0';ch=getchar();}
        return k;
    }
    
    void update(long long *arr,long long x,long long add){
        for(;x<=n;x+=x&-x) arr[x]+=add;
    }
    
    long long query(long long *arr,long long x){
        long long t=0;for(;x;x-=x&-x) t+=arr[x];return t;
    }
    
    int main(){
       n=read();long long las=0;
       for(long long i=1;i<=n;i++){
             long long y=read();update(c1,i,y-las);update(c2,i,(i-1)*(y-las));las=y;//i-1=n-(n-i+1)=>在前缀和中,y-las被加了(n-i+1)次,由于后来统计师算了n次,c[i]记录多算的数的大小 
       }
       q=read();
       for(long long i=1;i<=q;i++){
            long long flag=read(),l=read(),r=read();
            if(flag==1){
                 long long inc=read();
                 update(c1,l,inc);update(c1,r+1,-inc);//差分思想,c[i]记录差,则segma(c[1]~c[i])为数 i 的值 
                 update(c2,l,(l-1)*inc);update(c2,r+1,-r*inc);//同理 l-1=n-(n-l+1) r=n-(n-(r+1)+1)
            }
        else{
            long long sum1=(l-1)*query(c1,l-1)-query(c2,l-1);
            long long sum2=r*query(c1,r)-query(c2,r);
            printf("%lld\n",sum2-sum1);
        }
       }
       return 0;
    }
  • 相关阅读:
    (一)Kafka0.8.2官方文档中文版系列入门指南
    Hbase TTL(Time To Live)详解
    java源码学习详解Object类
    设计模式详细解读简单工厂方法模式
    (二)Kafka0.8.2官方文档中文版系列API
    Scala对象相等性判断
    scala中跳出循环的3种方法
    wpf 中借助 Grid 实现随着 Form 大小变化而按比例自动改变宽度或高度。
    static and cache
    约定编程之 Dictionary 的 String 类型的 Key
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/8570150.html
Copyright © 2011-2022 走看看