关闭

hdu 4031 问题分解+线段树+暴力

标签: acm线段树
65人阅读 评论(0) 收藏 举报
分类:
/*区间有两种情况
如果区间值为1则区间内的数处于同一状态,为0则不属于同一状态,要再分 
记录回复好的时间,如果查询时间》=这个时间,
则区间继续属于回复状态,更新父亲节点值
否则ans  = ans + (R-L + 1)
这种问题的复杂度不太好估计,最坏情况下要一直分下去,
感觉复杂度没有那么好保障
但是也能做吧
上面想的做法应该不对233

查了网上的做法……好像是N^2的算法啊
不会做的时候看看能不能分解问题?
先求出问题的一部分
先求出被攻击的次数,再减去防御的次数
防御的次数用暴力来统计,暴力统计的时候也要记录着,反正每次都是求当前值
可是他把t设置的这么小为什么……
这里学会用树状数组来区间更新,单点求值,比线段树方便不少。 
*/ 
#include<algorithm>
#include<cstdio>
#include<string.h> 
using namespace std;
const int maxn = 20050;
int tree[maxn];
int protect[maxn];
int left[maxn];
int right[maxn]; 
int time1[maxn];
int n;
int lowbit(int x)
{
	return x & -x;
}

int sum(int x)
{
	int ret = 0;
	while(x > 0){
		ret += tree[x];
		x -= lowbit(x);
	}
	return ret;
}

void add(int x,int d){
	while(x <= n){
		tree[x] += d;
		x += lowbit(x);
	}
}

int build()
{
	memset(tree,0,sizeof(tree));
	memset(protect,0,sizeof(protect));
	memset(left,0,sizeof(left));
	memset(right,0,sizeof(right));
	memset(time1,0,sizeof(time1));
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int test = 1; test <= t; test++){
    	printf("Case %d:\n",test);
    	int N,Q,CD;
    	scanf("%d %d %d",&N,&Q,&CD);
    	n = N;
    	build();
    	int cnt = 0;
    	for(int i = 1; i <= Q; i++){
    		char s[20];
    		scanf("%s",s);
    		if (s[0] == 'A'){
    			scanf("%d %d",&left[cnt],&right[cnt]);
    			add(left[cnt],1);
    			add(right[cnt] + 1,-1);
			    cnt++;
			}
			else{
			
				int where;
				scanf("%d",&where);
				for(int j = time1[where]; j < cnt; j++){
				    if (where >= left[j] && where <= right[j]){
				    	protect[where]++;
				    	time1[where] = j + CD;
				    	j = time1[where] - 1;
					}
				}
			    printf("%d\n",sum(where)- protect[where]);
			}
		}
    	
	}
	return 0;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5320次
    • 积分:561
    • 等级:
    • 排名:千里之外
    • 原创:52篇
    • 转载:2篇
    • 译文:1篇
    • 评论:0条
    文章分类