[kuangbin带你飞]专题七 线段树 F

来源:互联网 发布:php证书 编辑:程序博客网 时间:2024/05/22 00:55

https://vjudge.net/contest/66989#problem/F


给了每一线段的颜色,存在颜色覆盖,求表面上看能看到的颜色种类和各种颜色的段数

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define lid (id << 1)#define rid (id << 1 | 1)using namespace std;const int maxn = 8005;struct node{    int l, r, c;}tr[maxn*4];int cnt[maxn], temp;void push_down(int id){    if(tr[id].c!=-1)    {        tr[lid].c=tr[rid].c=tr[id].c;        tr[id].c=-1;    }}void Build (int id, int l, int r){    tr[id].l = l;tr[id].r = r;tr[id].c = -1;    if (l== r-1) return ;    else{        int mid=(l+r)>>1;        Build (id<<1, l, mid);        Build (id<<1|1, mid, r);    }}void update (int id, int l, int r, int c){//区间更新,    if (l==tr[id].l && tr[id].r==r) tr[id].c = c;    else{        push_down(id);        int mid = (tr[id].l+tr[id].r)>>1;        if (r <= mid) update (lid, l, r, c);        else if (l >= mid) update (rid, l, r, c);        else        {            update (lid, l, mid, c);            update (rid, mid, r, c);        }    }}void Count (int id){    if (tr[id].c != -1)    {//当前区间裸露在外面        if (tr[id].c != temp)//当前区间没有被统计过            cnt[tr[id].c] ++;        temp = tr[id].c;        return ;    }    if (tr[id].l == tr[id].r-1)    {//返回未被覆盖的区间,否则会栈溢出        temp = -1;        return ;    }    Count (lid);    Count (rid);}int main (){    int n, m;    while (scanf("%d",&n) != EOF)    {        Build (1,0,maxn);        while (n --)        {            int x, y, c;            scanf ("%d %d %d", &x, &y, &c);            update (1, x, y, c);        }        temp = -1;        memset (cnt,0,sizeof(cnt));        Count(1);        for (int i=0;i<maxn; i++)        if (cnt[i])        printf ("%d %d\n",i,cnt[i]);        printf ("\n");    }    return 0;}



原创粉丝点击