您的位置:首页 > 其它

HDU 1540 Tunnel Warfare

2015-04-05 15:03 169 查看
这题是数据结构题,用线段树做,设置两个数组,记录节点最大左连续值,节点右最大连续值,输出便有三种情况,节点左最大连续值,节点右最大连续值,和兄弟节点之间左右最大连续值相加,注意,此题有个坑,坑了我好久,输入时不止一组数据,要用while(!=EOF)来写.
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm> 
#include <stack>
#define maxn 50000
#define mem(a) memset(a, 0, sizeof(a))
using namespace std;

long lv[maxn * 4 + 5], rv[maxn * 4 + 5], nl[maxn * 4 + 5], nr[maxn * 4 + 5], flag, num;

void build(long l, long r, long n)
{
	nl
 = l;
	nr
 = r;
	if(l == r)
	{
		lv
 = 1;
		rv
 = 1;
		return;
	}
	long mid = (l + r) / 2;
	build(l, mid, n * 2);
	build(mid + 1, r, n * 2 + 1);
	rv
 = lv
 = lv[n * 2] + lv[n * 2 + 1];
}

void des(long l, long r, long n, long ll)
{
	if(l == r&&l == ll)
	{
		lv
 = 0;
		rv
 = 0;
		return;
	}
    long mid = (l + r) / 2;
	if(ll <= mid)
	des(l, mid, n * 2, ll);
	else
	des(mid + 1, r, n * 2 + 1, ll);
	if(rv[n * 2 + 1] == lv[n * 2 + 1]&&rv[n * 2 + 1] == (nr[n * 2 + 1] - nl[n * 2 + 1] + 1))
	rv
 = rv[n * 2 + 1] + rv[n * 2];
	else
	rv
 = rv[n * 2 + 1];
	if(rv[n * 2] == lv[n * 2]&&rv[n * 2] == (nr[n * 2] - nl[n * 2] + 1))
	lv
 = lv[n * 2] + lv[n * 2 + 1];
	else
	lv
 = lv[n * 2];
}

void rbt(long l, long r, long n, long ll)
{
	if(l == r&&l == ll)
	{
		lv
 = 1;
		rv
 = 1;
		return;
	}
    long mid = (l + r) / 2;
	if(ll <= mid)
	rbt(l, mid, n * 2, ll);
	else
	rbt(mid + 1, r, n * 2 + 1, ll);
	if(rv[n * 2 + 1] == lv[n * 2 + 1]&&rv[n * 2 + 1] == (nr[n * 2 + 1] - nl[n * 2 + 1] + 1))
	rv
 = rv[n * 2 + 1] + rv[n * 2];
	else
	rv
 = rv[n * 2 + 1];
	if(rv[n * 2] == lv[n * 2]&&rv[n * 2] == (nr[n * 2] - nl[n * 2] + 1))
	lv
 = lv[n * 2] + lv[n * 2 + 1];
	else
	lv
 = lv[n * 2];
}

void que(long l, long r, long n, long ll)
{
	if(flag == 1)
	return;
	if((lv
 + nl
 - 1) >= ll)
	{
		if(l != 1&&rv[n - 1])
		{
			printf("%ld\n",lv
 + rv[n - 1]);
		    flag = 1;
		    return;
		}
		printf("%ld\n", lv
);
		flag = 1;
		return;
	}
	if((nr
 - rv
 + 1) <= ll)
	{
		if(r != num&&lv[n + 1])
		{
			printf("%ld\n",rv
 + lv[n + 1]);
		    flag = 1;
		    return;
		}
		printf("%ld\n",rv
);
		flag = 1;
		return;
	}
	if(l == r)
	return;
	long mid = (l + r) / 2;
	if(ll <= mid)
	que(l, mid, n * 2, ll);
	else
	que(mid + 1, r, n * 2 + 1, ll);
}

int main(int argc, char *argv[])
{
	int i, j;
	long q, a;
	char ch;
	stack<long> st;
	while(scanf("%ld%ld%*c", &num, &q) != EOF)
	{
	    mem(lv);
	    mem(rv);
	    mem(nl);
	    mem(nr);
	    while(!st.empty())
	    {
    		st.pop();
    	}
	    build(1, num, 1);
	    for(i = 0;i < q;i++)
	    {
		    scanf("%c", &ch);
		    if(ch == 'D')
		    {
			    scanf("%ld%*c", &a);
			    des(1, num, 1, a);
			    st.push(a);
		    }
		    else if(ch == 'Q')
		    {
			    flag = 0;
			    scanf("%ld%*c", &a);
			    que(1, num, 1, a);
			    if(!flag)
			    printf("0\n");
		    }
		    else if(ch == 'R')
		    {
			    scanf("%*c");
			    a = st.top();
			    st.pop();
			    rbt(1, num, 1, a);
		    }
	    }
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: