题目描述:
给定一个长度为 n 的序列 {an},给出 m 次操作,操作有两种:
1 l r x,表示 al 到 ar 都加 x;
2 p,表示查询 ap 的值。
输入格式:
第一行包含两个正整数 n 和 m。
第二行包含 n 个数,表示 a1 到 an。
接下来 m 行,每行一个操作,操作一定为 1 l r x 或者 2 p 的形式。
输出格式:
对于每一个 2 操作,输出一行一个整数,表示查询的结果。
样例输入:
5 3
5 4 3 2 1
2 4
1 2 4 -3
2 4
样例输出:
2
-1
数据规模:
对于 60% 的数据,n,m≤1000。
对于 100% 的数据,2≤n≤105,1≤m≤105,|ai|≤1000,|x|≤1000。
这里我们先拓展一下树状数组:树状数组 - OI Wiki
这道题由于是一道模版题,所以线段树基本的函数就如下
int lowbit(int x){
return x&-x;
}
int get_sum(int x){
int res=0;
for(int i=x;i>0;i-=lowbit(i)){
res+=c[i];
}
return res;
}
int get_sum(int l,int r){
return get_sum(r)-get_sum(l-1);
}
void add(int x,int v) {
for(int i=x;i<=n;i+=lowbit(i)){
c[i]+=v;
}
}
你以为这道题这么简单,结果老师讲的时候才发现需要差分(⊙o⊙)…
signed main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
输入
b[i]=a[i]-a[i-1];差分
}
for(int i=1;i<=n;i++){
add(i,b[i]);
}
for(int i=1,op;i<=q;i++){
cin>>op;
if(op==1){判断这总没问题吧
int l,r,x;
cin>>l>>r>>x;
add(l,x);
add(r+1,-x);
}
else{
int x;
cin>>x;
cout<<get_sum(x)<<endl;
}
}
return 0;
}
如果你发现把这些代码平起来还没AC
你就得看一下要不要开long long了
最后一句总结
十年OI一场空,不开long long见祖宗