题目链接:http://codevs.cn/problem/1081/
这道题名字都叫线段树练习,但是之前用线段树a过后,最近正好学了分块算法,用来又做了一次——分块实在是优雅的暴力…竟然在代码如此之短,思想如此简单下还能保证这样的速度与效率…orz.建议大家学学.
#include<stdio.h>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=100005;
int w[maxn],bl[maxn],blo,tag[maxn],n,T;
inline const int read(){
register int f=1,x=0;
register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return f*x;
}
inline void add(int a,int b,int x){
for(int i=a;i<=min(bl[a]*blo,b);i++) w[i]+=x;
if(bl[a]!=bl[b])
for(int i=(bl[b]-1)*blo+1;i<=b;i++) w[i]+=x;
for(int i=bl[a]+1;i<=bl[b]-1;i++) tag[i]+=x;
}
int main(){
n=read(),blo=sqrt(n);
for(register int i=1;i<=n;i++) w[i]=read();
for(register int i=1;i<=n;i++) bl[i]=(i-1)/blo+1;
T=read();
int a,b,x,opt;
while(T--){
opt=read();
if(opt==1){
a=read(),b=read(),x=read();
add(a,b,x);
}
else a=read(),printf("%d\n",w[a]+tag[bl[a]]);
}
}