poj3777(线段树成段覆盖)

原创 2013年12月03日 19:38:35

题目链接:poj3777

/*poj 2777 Count Color 线段树成段覆盖,lazy
题目大意:
一段区间,初始值为1,两种操作,一种是修改,一种是查询

思路:线段树区间成段覆盖
建树是每个节点的标记color,初始值为1
涂色覆盖时,若完全覆盖,则color为颜色编号,
若覆盖一部分,则先将标记下放左右儿子,再将标号标记为-1
表示此节点被部分覆盖过。
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100005
int n,color;
struct node
{
    int l,r;
    int color;
}s[N<<2];
int ans[33];
void build(int l, int r, int n)
{
    s[n].l = l;
    s[n].r = r;
    s[n].color = 1;
    if(l == r) return;
    int mid = (l+r) >> 1;
    build(l, mid, n<<1);
    build(mid + 1, r, n<<1|1);
}
void update(int l, int r, int n)
{
    if(s[n].color == color) return;
    if(s[n].l == l && s[n].r == r)
    {
        s[n].color = color;
        return;
    }
    if(s[n].color != -1)
    {
        s[n<<1].color = s[n<<1|1].color = s[n].color;
        s[n].color = -1;
    }
    int mid = (s[n].l + s[n].r) >> 1;
    if(r <= mid)
        update(l, r, n<<1);
    else if(l > mid)
        update(l, r, n<<1|1);
    else
    {
        update(l, mid, n<<1);
        update(mid+1, r, n<<1|1);
    }
}

void query(int l, int r, int n)
{
    if(s[n].color != -1 )
    {
        ans[ s[n].color ] ++;
        return;
    }
    int mid = (s[n].l + s[n].r) >> 1;
    if(r <= mid)
        query(l, r, n<<1);
    else if(l > mid)
        query(l, r, n<<1|1);
    else
    {
        query(l, mid, n<<1);
        query(mid+1, r, n<<1|1);
    }
}

int main()
{
	int i,m,x,y,t,tot;
	char ch[2];
	while(~scanf("%d%d%d",&m,&tot,&t))
	{
	    build(1,m,1);
	    while(t--)
	    {
	        scanf("%s",ch);
	        if(ch[0] == 'C')
	        {
	            scanf("%d%d%d",&x,&y,&color);
	            if(x > y) swap(x,y);
	            update(x,y,1);
	        }
	        else if(ch[0] == 'P')
	        {
	            memset(ans, 0, sizeof(ans));
	            scanf("%d%d",&x,&y);
	            if(x > y) swap(x,y);
	            query(x,y,1);
	            int sum = 0;
	            for(int j = 1; j <= 30; j ++)
	            if(ans[j]) sum++;
	            printf("%d\n",sum);
	        }
	    }
	}
	return 0;
}


线段树详解(单点更新与成段更新\区间更新操作)

本文纯属原创,转载请注明出处,谢谢。 距离第一次接触线段树已经一年多了,再次参加ACM暑假集训,这一次轮到我们这些老家伙们给学弟学妹们讲解线段树了,所以就自己重新把自己做过的题目看了一遍,然后写篇博客...
  • u014705673
  • u014705673
  • 2015年07月06日 15:57
  • 6275

poj 2528 Mayor's posters(线段树区间覆盖、离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 49385   Accepted:...
  • aaaaacmer
  • aaaaacmer
  • 2015年07月28日 11:12
  • 704

求区间最大子段和(线段树)

填坑。。。 线段树需要维护的是: 左端点 x 右端点 y (本人喜欢直接维护端点) [x,y]内的最大子段和 ms [x,y]的区间和 s [x,y]内的紧靠左端点的最大子段和 ls ...
  • wu_tongtong
  • wu_tongtong
  • 2017年06月17日 20:39
  • 695

poj2482(最多矩形覆盖-线段树)

题意:二维平面上有一些星星,每个星星都有一个亮度值,给一个矩形,矩形两边平行于坐标轴,只能平移不可以旋转,问矩形覆盖面积内的星星的亮度值之和最大是多少? 解法:将模型转化为:每个星星都是一个...
  • xiefubao
  • xiefubao
  • 2014年04月22日 15:18
  • 790

线段树模板合集--单点替换,区间替换,区间增加3种情况

单点替换,单点增加,区间求最值,区间求和#include #include #include using namespace std; #define lson l , m , rt ...
  • qq547276542
  • qq547276542
  • 2016年05月30日 11:46
  • 3064

线段覆盖长度

 给定一些线段,线段有起点和终点,求这些线段的覆盖长度,重复的部分只计算一次。 方法一: 首先说排序对于处理很多问题都是非常有效的,例如寻找兄弟单词等问题中,经过排序处理后,问题就明...
  • wwj_ff
  • wwj_ff
  • 2015年09月01日 15:03
  • 1139

关于线段树懒惰标记的理解,成段更新(poj 3468为例)

懒惰标记实际上就是让子节点暂时处于不更新状态,用到的时候再更新,如本题中的visit[]就是懒惰标记,例如总长度是1-10,我们现在要想更新1-6,(将1-6的值都加3)那么update()会先找1-...
  • sdjzping
  • sdjzping
  • 2014年02月20日 10:10
  • 1746

GSS 1 区间最大子段和

GSS 1   区间最大子段和    刚学线段树,在codevs上做完线段树练习1-3,然后高二神犇LTY给我看了这个GSS系列,今天下午终于做完了。之前好多题都没往博客上写,之后到寒假会慢慢补。 ...
  • wbxdhr
  • wbxdhr
  • 2017年01月13日 16:52
  • 229

线段树单标记,双标记

单标记(区间维护)#include #include #include #include #include #include #define LL long long #define ls...
  • qq_33183401
  • qq_33183401
  • 2016年08月05日 22:48
  • 574

[线段树练习4] 线段颜色条数 - 统计标记总数

题目描述X轴上从下向上依次叠放一定长度的某种颜色的线段。问从上向下看X轴,它被分成了不同颜色的多少段?输入格式第1行:2个整数XC,N。XC表示X轴的颜色,1...
  • Bill_Yang_2016
  • Bill_Yang_2016
  • 2017年02月05日 23:36
  • 201
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj3777(线段树成段覆盖)
举报原因:
原因补充:

(最多只允许输入30个字)