• C


    - 题目大意

        D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少,然后根据命令来进行模拟操作。

    - 解题思路

      这个我是根据线段树的区间合并的模板来写的,用三个变量记录左边连续区间,右边连续区间和最大连续区间,用栈来存储点(修复的时候要用),其余的就是更新点,然后查询最大的连续区间。

    - 代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstring>
    #include<stack>
    using namespace std;
    const int maxn = 50001;
    struct node
    {
    	int l, r;
    	int ls, rs, ms;
    }t[4 * maxn];
    
    void build(int l, int r, int k)
    {
    	int mid;
    	t[k].l = l;
    	t[k].r = r;
    	t[k].ls = t[k].rs = t[k].ms = r - l + 1;
    	if (l == r)
    	  return;
        mid = (l + r) / 2;
        build(l, mid, 2 * k);
        build(mid + 1, r, 2 * k + 1);
    
    }
    
    void add(int i, int r, int x)
    {
    	int mid;
    	if (t[i].r == t[i].l)
    	{
    		t[i].ls = t[i].rs = t[i].ms = x;
    		return;
    	}
    	mid = (t[i].r + t[i].l) / 2;
    	if (r <= mid)
    		add(2 * i, r, x);
    	else
    		add(2 * i + 1, r, x);
    	if (t[i * 2].ls == t[i * 2].r - t[i * 2].l + 1)
    		t[i].ls = t[i * 2].ls + t[i * 2 + 1].ls;
    	else
    		t[i].ls = t[i * 2].ls;
    	if (t[i * 2 + 1].rs == t[i * 2 + 1].r - t[i * 2 + 1].l + 1)
    		t[i].rs = t[i * 2 + 1].rs + t[i * 2].rs;
    	else
    		t[i].rs = t[i * 2 + 1].rs;
    	t[i].ms = max(max(t[i * 2].ms, t[i * 2 + 1].ms), t[i * 2].rs + t[i * 2 + 1].ls);
    
    }
    
    int findd(int k, int r)
    {
    	int mid;
    	if (t[k].l == t[k].r || t[k].ms == 0 || t[k].ms == t[k].r - t[k].l + 1)
    	{
    		return t[k].ms;
    	}
    	mid = (t[k].r + t[k].l) / 2;
    	if (r <= mid)
    	{
    		if (r >= t[2 * k].r - t[2 * k].rs + 1)
    			return t[k * 2].rs + t[k * 2 + 1].ls;
    		else
    			return findd(2 * k, r);
    	}
    	else
    	{
    		if (r <= t[2 * k + 1].l + t[2 * k + 1].ls - 1)
    			return t[k * 2 + 1].ls + t[k * 2].rs;
    		else
    			return findd(2 * k + 1, r);
    	}
    }
    int main()
    {
    	int n, m, a;
    	char str[10];
    	while(~scanf("%d%d", &n, &m))
    	{
        build(1, n, 1);
    	stack<int>q;
    	if(!q.empty())
            q.pop();
    	while (m--)
    	{
    		scanf("%s", str);
    		if (str[0] == 'D')
    		{
    			scanf("%d", &a);
    			q.push(a);
    			add(1, a, 0);
    		}
    		else if (str[0] == 'Q')
    		{
    			scanf("%d", &a);
    			printf("%d
    ", findd(1, a));
    		}
    		else if (str[0] == 'R')
    		{
    			a = q.top();
    			q.pop();
    			add(1, a, 1);
    		}
    	}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    net过滤表单和url参数
    html mailto
    sql提取汉字拼音首字母
    使用jquery获取radio的值
    net文件服务器配置
    如何将简体字保存到繁体数据库而不会出现乱码
    net直接下载文件
    java开发:笔记
    android开发:LogCat失效,adb失效
    编程记事本
  • 原文地址:https://www.cnblogs.com/alpacadh/p/8521606.html
Copyright © 2020-2023  润新知