1. 程式人生 > >hdu 6183 Color it(線段樹)

hdu 6183 Color it(線段樹)

php 每次 alt using update -a pac flag aps

題目鏈接: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\n",ans); 58 } 59 } 60 return 0; 61 }
View Code

hdu 6183 Color it(線段樹)