1081 线段树练习 2

来源:互联网 发布:excel2003重复数据 编辑:程序博客网 时间:2024/06/08 19:28

给你N个数,有两种操作


1:给区间[a,b]的所有数都增加X


2:询问第i个数是什么?

第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。

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

3

1

2

3

2

1 2 3 2

2 3

5

数据范围

1<=n<=100000

1<=q<=100000

#include<iostream>
#include<string.h>
using namespace std;
int n,num[100005];
long long ans;
struct node
{
    int l;
    int r;
    long long sum;
    long long add;
};
node tree[3*100005];
void build(int v,int l,int r)
{
    tree[v].l=l;
    tree[v].r=r;
    tree[v].sum=0;
    tree[v].add=0;
    if(l==r)
    {
        tree[v].sum=num[l];
        return ;
    }
    int mid=(l+r)/2;
    build(2*v,l,mid);
    build(2*v+1,mid+1,r);
    tree[v].sum=tree[2*v].sum+tree[2*v+1].sum;
}
void update(int v,int l,int r,int add)
{
    if(tree[v].l > r || tree[v].r < l)
    {return ;}
    if(tree[v].l >= l && tree[v].r <= r)
    {
      tree[v].sum += (tree[v].r-tree[v].l+1)*add;
      tree[v].add += add;
      return ;
    }
    if(tree[v].add)
    {
      tree[2*v].sum += (tree[2*v].r-tree[2*v].l+1)*tree[v].add;
      tree[2*v].add += tree[v].add;
      tree[2*v+1].sum += (tree[2*v+1].r-tree[2*v+1].l+1)*tree[v].add;
      tree[2*v+1].add += tree[v].add;
      tree[v].add = 0;
    }
    update(2*v,l,r,add);
    update(2*v+1,l,r,add);
    tree[v].sum = tree[2*v].sum + tree[2*v+1].sum;
}
void query(int v,int l,int r)
{
   if(tree[v].l > r || tree[v].r < l)
    {return ;}
    if(tree[v].l>=l&&tree[v].r<=r)
    {
        ans=ans+tree[v].sum;
        return ;
    }
    if(tree[v].add)
    {
      tree[2*v].sum += (tree[2*v].r-tree[2*v].l+1)*tree[v].add;
      tree[2*v].add += tree[v].add;
      tree[2*v+1].sum += (tree[2*v+1].r-tree[2*v+1].l+1)*tree[v].add;
      tree[2*v+1].add += tree[v].add;
      tree[v].add = 0;
    }
    query(2*v,l,r);
    query(2*v+1,l,r);
    tree[v].sum = tree[2*v].sum + tree[2*v+1].sum;
}
int main()
{
    while(cin>>n)
    {
        int i,j,m;
        for(i=1;i<=n;i++)
            cin>>num[i];
        build(1,1,n);
        cin>>m;
        int x1,x2,x3,x4;
        for(i=0;i<m;i++)
        {
            cin>>x1;
            if(x1==1)
            {
                 cin>>x2>>x3>>x4;
            update(1,x2,x3,x4);
            }
            if(x1==2)
            {
                cin>>x2;
                ans=0;
                query(1,x2,x2);
                cout<<ans<<endl;
            }

        }
    }
    return 0;
}