HDU6183 Color it【线段树】

来源:互联网 发布:做不喜欢的事 知乎 编辑:程序博客网 时间:2024/05/16 07:03

题意:一个二维平面,三种操作,1.清空所有点,2.在(x,y)上加一种颜色(不是覆盖),3.查询区域1~x,y1~y2这个二维区域内有几种颜色


思路:考虑给每种颜色建一颗线段树,维护的是一段y(几行)内这种颜色出现的最小的x,查询:y1-y2内的最小值比x小,那么区域内有这种颜色。由于空间的限制,需要动态开点。还可以把坐标离散化。


#include<bits/stdc++.h>using namespace std;const int maxn=1.5e5+10;struct data{int l,r,num;}node[maxn*30];int p[maxn][4],tot;int row,con,root[55],flag;vector<int> v1,v2;int newnode(){node[tot].num = 0x3f3f3f3f;node[tot].l = node[tot].r = -1;return tot++;}void up(int ny,int x,int y,int &cnt,int val){if(cnt == -1) cnt = newnode();node[cnt].num = min(node[cnt].num,val);if(x == y) return;int mid = (x+y) / 2;if(ny <= mid)up(ny,x,mid,node[cnt].l,val);elseup(ny,mid+1,y,node[cnt].r,val);}void fid(int qx,int qy,int x,int y,int cnt,int k){if(flag) return;if((node[cnt].l == -1 && node[cnt].r == -1) || (qx == x && qy ==y)){if(node[cnt].num <= k)flag = 1;return;}int mid = (x+y) / 2;if(qy <= mid){if(node[cnt].l != -1)fid(qx,qy,x,mid,node[cnt].l,k);}else if(qx >= mid+1){if(node[cnt].r != -1)fid(qx,qy,mid+1,y,node[cnt].r,k);}else    {    if(node[cnt].l != -1)        fid(qx,mid,x,mid,node[cnt].l,k);        if(node[cnt].r != -1)fid(mid+1,qy,mid+1,y,node[cnt].r,k);    }}int qurey(int x2,int y1,int y2){    int num = 0;    for(int i = 0; i <= 50; i++)    {    flag = 0;fid(y1,y2,1,row,root[i],x2);    num += flag;}    return num;}int main(){    int op,t,en = 0;    while(scanf("%d",&op)!=EOF && op != 3)    {        t = 1;        if(op != 0)        {            p[1][0] = op;            scanf("%d%d%d",&p[1][1],&p[1][2],&p[1][3]);            t++;        }        while(scanf("%d",&op)!=EOF)        {            if(op == 3)            {                en = 1;                break;            }            if(op != 0)            {                p[t][0] = op;                scanf("%d%d%d",&p[t][1],&p[t][2],&p[t][3]);                t++;            }            else                break;        }        v1.clear();        v2.clear();        for(int i = 1; i < t; i++)        {            if(p[i][0] == 1)            {                v1.push_back(p[i][1]);                v2.push_back(p[i][2]);            }            else            {                v1.push_back(p[i][1]);                v2.push_back(p[i][2]);                v2.push_back(p[i][3]);            }        }        sort(v1.begin(),v1.end());        sort(v2.begin(),v2.end());        v1.erase(unique(v1.begin(),v1.end()),v1.end());        v2.erase(unique(v2.begin(),v2.end()),v2.end());        con = v1.size();        row = v2.size();        tot = 0;        for(int i = 0; i <= 50; i++)        {            root[i] = newnode();        }        for(int i = 1; i < t; i++)        {            if(p[i][0] == 1)            {                int x1 = lower_bound(v1.begin(),v1.end(),p[i][1]) - v1.begin() + 1;                int y1 = lower_bound(v2.begin(),v2.end(),p[i][2]) - v2.begin() + 1;                up(y1,1,row,root[p[i][3]],x1);            }            else            {                int x2 = lower_bound(v1.begin(),v1.end(),p[i][1]) - v1.begin() + 1;                int y1 = lower_bound(v2.begin(),v2.end(),p[i][2]) - v2.begin() + 1;                int y2 = lower_bound(v2.begin(),v2.end(),p[i][3]) - v2.begin() + 1;                printf("%d\n",qurey(x2,y1,y2));            }        }        if(en)            break;    }    return 0;}