hdu 6183 Color it(线段树)

题目链接:hdu 6183 Color it

题意:

在一个二维平面上有n个操作。

1. x y c 在(x,y)这点上添加一个颜色c。

2. x y1 y2 询问二维平面[1,x]~[y1,y2]上有多少不同的颜色。

题解:

由于这题在x轴每次都是询问的[1,x],所以我们开50棵线段树,对于每种颜色维护每个y坐标的最小x,查询的时候就是区间查询[y1,y2]的最小x是否小于当前查询的x。

这里由于空间有限制,要用最原始版本的线段树,动态开点。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;++i)
 3 using namespace std;
 4 
 5 const int M=3e6+7,N=1e6;
 6 struct Node{int l,r,v;}T[M];
 7 int tot,rt[51],flag,a,b,c,d;
 8 
 9 void update(int x,int v,int &rt,int l=1,int r=N)
10 {
11     if(!rt)T[rt=++tot]=Node{0,0,v};
12     if(T[rt].v>v)T[rt].v=v;
13     if(l==r)return;
14     int mid=l+r>>1;
15     if(x<=mid)update(x,v,T[rt].l,l,mid);
16     else update(x,v,T[rt].r,mid+1,r);
17 }
18 
19 void ask(int L,int R,int rt,int x,int l=1,int r=N)
20 {
21     if(flag||!rt)return;
22     if(L<=l&&r<=R)
23     {
24         if(T[rt].v<=x)flag=1;
25         return;
26     }
27     int mid=l+r>>1;
28     if(L<=mid)ask(L,R,T[rt].l,x,l,mid);
29     if(R>mid)ask(L,R,T[rt].r,x,mid+1,r);
30 }
31 
32 int main(){
33     while(1)
34     {
35         scanf("%d",&a);
36         if(a==3)break;
37         if(a==0)
38         {
39             F(i,0,50)rt[i]=0;
40             tot=0;
41         }
42         if(a==1)
43         {
44             scanf("%d%d%d",&b,&c,&d);
45             update(c,b,rt[d]);
46         }
47         if(a==2)
48         {
49             scanf("%d%d%d",&b,&c,&d);
50             int ans=0;
51             F(i,0,50)
52             {
53                 flag=0;
54                 ask(c,d,rt[i],b);
55                 ans+=flag;
56             }
57             printf("%d
",ans);
58         }
59     }
60     return 0;
61 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/7462431.html