此题为洛谷P3368
有些一些是转载于此:
https://www.cnblogs.com/hsd-/p/6139376.html
顺带总结一下最近学的树状数组(笑)
#include<bits/stdc++.h> using namespace std; int n,m; long long a[50000005]; int lowbit(int x){ return x&(-x);//-t 代表t的负数 计算机中负数使用对应的正数的补码来表示 }//印象中是树状数组最主要的结构!!! //lowbit(x) 其实就是取出x的最低位1 void add(long long p,long long x){ while(p<=n) { a[p]+=x; p+=lowbit(p); }//可以发现 更新过程是查询过程的逆过程 //由叶子结点向上更新C[]数组 } int find(long long p){ long long ans=0; while(p>0) { ans+=a[p]; p-=lowbit(p); }//利用C[i]数组,求A数组中前i项的和 return ans; } int main(){ scanf("%d%d",&n,&m); long long last = 0, now; for (int i = 1; i <= n; i++) { scanf("%lld", &now); add(i, now - last); last = now; } int f; while (m--) { scanf("%d", &f); if (f == 1) { int x, y; long long k; scanf("%d%d%lld", &x, &y, &k); add(x, k); add(y + 1, -k); } else if (f==2) { int t; scanf("%d", &t); printf("%lld ", find(t)); } } return 0; }
作为小juluo的我竟然自己总结(假的)
希望对每个和我一样的juluo又一点想法,嘻嘻!!!
洛谷里好像还有一题,
P3374 传送门
题解:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int n,m,tree[2000010]; int lowbit(int x){ return x&(-x); } void add(int x,int k){ for(int i=x;i<=n;i+=lowbit(i))tree[i]+=k; } int find(int x){ int sum=0; for(int i=x;i;i-=lowbit(i))sum+=tree[i]; return sum; } int main(){ cin>>n>>m; for(int i=1;i<=n;i++){ int a; cin>>a; add(i,a); } for(int i=1;i<=m;i++){ int a,b,c; cin>>a>>b>>c; if(a==1)add(b,c); else cout<<find(c)-find(b-1)<<endl; } return 0; }
总结一下
其实在树状数组中lowbit函数是最关键的,
因为它操纵了整个树状数组(笑)