题目描述 Description
给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么?
输入描述 Input Description
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
输出描述 Output Description
对于每个询问输出一行一个答案
样例输入 Sample Input
3
1
2
3
2
1 2 3 2
2 3
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
数据范围
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;
}