zoukankan      html  css  js  c++  java
  • Codevs 1080 线段树联系

    题目描述 Description

    一行N个方格,开始每个格子里都有一个整数。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N<100000,,提问和修改的总数m<10000条。

    输入描述 Input Description

    输入文件第一行为一个整数N,接下来是n行n个整数,表示格子中原来的整数。接下一个正整数m,再接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。

    输出描述 Output Description

    共m行,每个整数

    样例输入 Sample Input

    6

    3

    4

    1 3 5

    2 1 4

    1 1 9

    2 2 6

    样例输出 Sample Output

    22

    22

    数据范围及提示 Data Size & Hint

    1≤N≤100000, m≤10000 。

    树状数组:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int n,m,t[1000];
     6 void add(int k,int z)
     7 {
     8     while(k<=n)
     9     {
    10         t[k]+=z;
    11         k+=k&(-k);
    12     }
    13 }
    14 int find(int x)
    15 {
    16     int ans=0;
    17     while(x)
    18     {
    19         ans+=t[x];
    20         x-=x&(-x);
    21     }
    22     return ans;
    23 }
    24 int main()
    25 {
    26     cin>>n;
    27     for(int i=1;i<=n;i++)
    28     {
    29         int x;
    30         cin>>x;
    31         add(i,x); 
    32     }
    33     cin>>m;
    34     for(int i=1;i<=m;i++)
    35     {
    36         int a,b,c,d,e;
    37         cin>>a;
    38         if(a==1) {
    39             cin>>b>>c;
    40             add(b,c);
    41         }
    42         if(a==2)
    43         {
    44             cin>>d>>e;
    45             printf("%d
    ",find(e)-find(d-1));
    46         }
    47     }
    48     
    49     return 0;
    50 }
    View Code

    线段树:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int n,m;
     6 struct node{
     7     int l,r,sum;
     8 };
     9 node tr[100010*4];
    10 void built(int l,int r,int k)//建树 
    11 {
    12     tr[k].l=l;tr[k].r=r;
    13     if(l==r) {scanf("%d",&tr[k].sum);return;}
    14     int mid=(l+r)/2;
    15     built(l,mid,k*2);built(mid+1,r,k*2+1);
    16     tr[k].sum=tr[k*2].sum+tr[k*2+1].sum;
    17 }
    18 void change(int k,int pos,int x)
    19 {
    20     int l=tr[k].l;int r=tr[k].r;    if(l==r) {tr[k].sum=tr[k].sum+x;return;}
    21     int mid=(l+r)/2;
    22     if(pos<=mid) change(k*2,pos,x);
    23     if(pos>mid) change(k*2+1,pos,x);
    24     tr[k].sum=tr[k*2].sum+tr[k*2+1].sum;
    25 }
    26 int que(int k,int l,int r)
    27 {
    28     int ans=0;
    29     if(l==tr[k].l&&tr[k].r==r) {return tr[k].sum;}
    30     int mid=(tr[k].l+tr[k].r)/2;
    31     if(l<=mid) ans+=que(k*2,l,min(r,mid));
    32     if(r>mid) ans+=que(k*2+1,max(mid+1,l),r);
    33     return ans;
    34 }
    35 int main()
    36 {
    37     scanf("%d",&n);
    38     built(1,n,1);
    39     scanf("%d",&m);
    40     for(int i=1;i<=m;i++)
    41     {
    42         int a,x,A,d,c;
    43         cin>>a;
    44         if(a==1)
    45         {
    46             cin>>x>>A;
    47             change(1,x,A);
    48         }
    49         if(a==2)
    50         {
    51             cin>>c>>d;
    52             printf("%d
    ",que(1,c,d));
    53         }
    54     }
    55     return 0;
    56 } 
    View Code
  • 相关阅读:
    C++ Primer读书笔记
    谨慎使用多线程中的fork
    C++中多线程与Singleton的那些事儿
    浅谈指针的比较
    条件变量的陷阱与思考
    2014年终总结
    循环队列的一种实现模型
    react-native使用jest、enzyme进行单元测试
    富文本编辑器开发原理
    模拟实现单元测试中的异步测试
  • 原文地址:https://www.cnblogs.com/suishiguang/p/5906086.html
Copyright © 2011-2022 走看看