树状数组区间修改单点查询

Morning_Glory

2018-09-17 14:10:44

Personal

```cpp #include <cstdio> using namespace std; const int maxn = 500005; int cha[maxn],tree[maxn],bj[maxn],n,m,t,last,opre,p,q,k;//cha -> 差分数组,tree -> 差分数组的树状数组,bj -> 标记数组 int read (void)//读入优化 { int res=0; bool flag=false; char ch; while ((ch=getchar())>'9'||ch<'0') if (ch=='-')flag=true; while (ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar(); if (flag)return ~res+1; return res; } int lowbit (int x) { return x & -x; } int input (void) { n=read(),m=read(); for (int i=1;i<=n;i++){ t=read();//有了差分数组就不需要存这些值了 int cnt=0; cha[i]=t-last;//差分数组,每次求当前值与上一值的差 last=t; for (int j=i;cnt<lowbit(i);--j,++cnt) tree[i]+=cha[j];//求出差分数组的树状数组 } } void add (int x,int y,int w) { //将区间[x,y]的值加w int cnt=0; for (int i=x;i<=n;i+=lowbit(i))tree[i]+=w; for (int i=y+1;i<=n;i+=lowbit(i))tree[i]-=w; } int query (int k) { int res=0; //查询第k个数的值 while (k>0){ res+=tree[k]; k-=lowbit(k); } return res; } int main () { input(); while (m--){ opre=read(),p=read(); if (opre==1){ q=read(),k=read(); add(p,q,k); } else printf("%d\n",query(p)); } return 0; } ```