• 线段数例题1


    描述:

    假设有一列数{Ai}(1≤i≤n),支持如下两种操作:
     1.将Ak的值加d。(k, d是输入的数)
     2.输出As+As+1+…+At。(s, t都是输入的数,s≤t)

    输入:

    第一行一个整数n,表示数列元素个数
    第二行为n个整数,表示{Ai}的初始值。
    第三行为一个整数m,表示操作数下接m行,每行描述一个操作,有如下两种情况:
    ADD k d (表示将Ak加d,1<=k<=n,d为数)
    SUM s t (表示输出As+…+At)

    输出:

    对于每一个SUM提问,输出结果

    样例输入:

    5

    1 2 3 2 4

    5

    SUM 1 2

    SUM 1 5

    ADD 1 2

    SUM 1 2

    SUM 1 5

    样例输出:

    3

    12

    5

    14

    数据规模   m,n<=100000

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    
    int n,m,k,d,s,t,a[100010],sum[100010];
    int p=0;
    struct node
    {
        int a,b,left,right,v;
    };
    node tree[400000];
    void build(int x,int y)
    {
         p++; 
         int now=p;
         tree[now].a=x; 
         tree[now].b=y;     
         tree[now].v=sum[y]-sum[x-1];
         if(x<y)
         {
                tree[now].left=p+1;
                build(x,(x+y)/2);
                tree[now].right=p+1;  
                build((x+y)/2+1,y);
         }
    }
    void add(int r)
    {
         tree[r].v=tree[r].v+d;
         if(tree[r].left!=0&&tree[tree[r].left].a<=k&&tree[tree[r].left].b>=k)
             add(tree[r].left);
         if(tree[r].right!=0&&tree[tree[r].right].a<=k&&tree[tree[r].right].b>=k)
            add(tree[r].right);
    }
    int  getsum(int r)
    {    
        int La,Lb,Ra,Rb;
        int tot=0;
        if(s<=tree[r].a&&tree[r].b<=t)
          return tree[r].v;
        else
        {
               La=tree[tree[r].left].a;
               Lb=tree[tree[r].left].b;
               if(!(La>t||Lb<s))
                 tot=tot+getsum(tree[r].left);
               Ra=tree[tree[r].right].a;
               Rb=tree[tree[r].right].b;
               if(!(Ra>t||Rb<s))
                 tot=tot+getsum(tree[r].right);
               return tot;
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        build(1,n);
        scanf("%d",&m);
        while(m--)
        {
            char ch[10];
            scanf("%s",ch);
            if(ch[0]=='A')
            {
                scanf("%d%d",&k,&d);
                add(1);
            } 
            if(ch[0]=='S')
            {
                scanf("%d%d",&s,&t);
                printf("%d\n",getsum(1));
            }
        }
        return 0;
    }
  • 相关阅读:
    c# 复制整个文件夹的内容,Copy所有文件
    c# 创建文件夹
    c# 访问共享文件
    sublimit 编辑器 设置默认的编码
    WPF xml配置文件里面的大于小于号转义
    c# datatable 分组
    WPF 耗时操作时,加载loging 动画 (BackgroundWorker 使用方法)
    WPF DEV gridcontrol 自定义计算列(TotalSummary)
    postgresql 创建gin索引
    WPF DEV gridcontrol当前项的数据导出为mdb文件
  • 原文地址:https://www.cnblogs.com/wanghaixv/p/8496141.html
Copyright © 2020-2023  润新知