首页 > 其他 > 详细

HDU1556 Color the ball 树状数组 修改区间值 查找单点值

时间:2014-04-22 00:00:46      阅读:494      评论:0      收藏:0      [点我收藏+]

以前记得看到过树状数组能做的   线段树肯定可以做,反过来不行  这句话,所以没去学树状数组,现在补一下吧


看到这道题,还是手痒敲了一把线段树,可是不知道为什么超时了,改了几把还是超时,真心不知道哪里出问题了,后来看了别人的题解,发现没什么他们的跟我的没什么大区别,后来复制了他们的去交了一把,发现大家的都超时了,可能题目的数据范围被被修改了,不过还是贴出超时,代码希望路过有大神可以指点一下




还有可以先做一下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;
}



还有可以先做一下POJ2309,有助于理解树状数组

HDU1556 Color the ball 树状数组 修改区间值 查找单点值,布布扣,bubuko.com

HDU1556 Color the ball 树状数组 修改区间值 查找单点值

原文:http://blog.csdn.net/yitiaodacaidog/article/details/24270351

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!