以前记得看到过树状数组能做的 线段树肯定可以做,反过来不行 这句话,所以没去学树状数组,现在补一下吧
看到这道题,还是手痒敲了一把线段树,可是不知道为什么超时了,改了几把还是超时,真心不知道哪里出问题了,后来看了别人的题解,发现没什么他们的跟我的没什么大区别,后来复制了他们的去交了一把,发现大家的都超时了,可能题目的数据范围被被修改了,不过还是贴出超时,代码希望路过有大神可以指点一下
还有可以先做一下POJ2309,有助于理解树状数组
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #include<cctype> #define ll long long #define LL __int64 #define eps 1e-8 //const ll INF=9999999999999; #define inf 0xfffffff using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int> P; //vector<pair<int,int>> ::iterator iter; // //map<ll,int>mp; //map<ll,int>::iterator p; const int N = 300000 + 10; typedef struct Node { int left,right,mid; int sum,cnt; }; Node tree[N]; void build_Tree(int left,int right,int root) { tree[root].left = left; tree[root].right = right; tree[root].mid = (left + right)/2; tree[root].sum = 0; if(left == right)return; build_Tree(left,tree[root].mid,2 * root); build_Tree(tree[root].mid + 1,right, 2 * root + 1); } void update(int left,int right,int root) { if(tree[root].left == tree[root].right) { tree[root].sum++; return; } if(left > tree[root].mid) update(left,right,2 * root + 1); else if(right <= tree[root].mid) update(left,right,2 * root); else { update(left,tree[root].mid,2 * root); update(tree[root].mid + 1,right,2 * root + 1); } } int ans; void find(int pos,int root) { ans += tree[root].sum; if(tree[root].left == tree[root].right && tree[root].left == pos)return; if(pos <= tree[root].mid) find(pos,2 * root); else find(pos,2 * root + 1); } int main() { int n; int x,y; while(scanf("%d",&n),n) { build_Tree(1,n,1); for(int i=0;i<n;i++) { scanf("%d %d",&x,&y); update(x,y,1); } for(int i=1;i<n;i++) { ans = 0; find(i,1); printf("%d ",ans); } ans = 0; find(n,1); printf("%d\n",ans); } return 0; }
树状数组的,那就是先成段更新 再查找某一点的值了
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #include<cctype> #define ll long long #define LL __int64 #define eps 1e-8 //const ll INF=9999999999999; #define inf 0xfffffff using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int> P; //vector<pair<int,int>> ::iterator iter; // //map<ll,int>mp; //map<ll,int>::iterator p; const int N = 100000 + 10; int c[N]; int n; void clear() { memset(c,0,sizeof(c)); } int lowbit(int x) { return x&(-x); } //设原始矩阵为a,将a[i]加上val时对c所做的修改 void update(int i, int val) { while (i <= n) { c[i]+=val; i += lowbit(i); } } //求前i项元素的和 int get_sum(int i) { int sum=0; while (i > 0) { sum += c[i]; i -= lowbit(i); } return sum; } int main() { int x,y; while(scanf("%d",&n),n) { clear(); for(int i=0;i<n;i++) { scanf("%d %d",&x,&y); update(x,1); update(y+1,-1); } for(int i=1;i<n;i++) printf("%d ",get_sum(i)); printf("%d\n",get_sum(n)); } return 0; }
HDU1556 Color the ball 树状数组 修改区间值 查找单点值,布布扣,bubuko.com
HDU1556 Color the ball 树状数组 修改区间值 查找单点值
原文:http://blog.csdn.net/yitiaodacaidog/article/details/24270351