hdu 6183 Color it (line segment tree dynamic opening point)

Do you like painting? Little D doesn't like painting, especially messy color paintings. Now Little B is painting. To prevent him from drawing messy painting, Little D asks you to write a program to maintain following operations. The specific format of these operations is as follows. 

00 : clear all the points. 

1xycc : add a point which color is cc at point (x,y)(x,y). 

2xy1y1 y2y2 : count how many different colors in the square (1,y1)(1,y1) and (x,y2)(x,y2). That is to say, if there is a point (a,b)(a,b) colored cc, that 1ax1≤a≤x and y1by2y1≤b≤y2, then the color cc should be counted. 

33 : exit. 

InputThe input contains many lines. 

Each line contains a operation. It may be '0', '1 x y c' ( 1x,y106,0c501≤x,y≤106,0≤c≤50), '2 x y1 y2' (1x,y1,y21061≤x,y1,y2≤106 ) or '3'. 

x,y,c,y1,y2x,y,c,y1,y2 are all integers. 

Assume the last operation is 3 and it appears only once. 

There are at most 150000150000 continuous operations of operation 1 and operation 2. 

There are at most 1010 operation 0. 

OutputFor each operation 2, output an integer means the answer . 
Sample Input

0
1 1000000 1000000 50
1 1000000 999999 0
1 1000000 999999 0
1 1000000 1000000 49
2 1000000 1000000 1000000
2 1000000 1 1000000
0
1 1 1 1
2 1 1 2
1 1 2 2
2 1 1 2
1 2 2 2
2 1 1 2
1 2 1 3
2 2 1 2
2 10 1 2
2 10 2 2
0
1 1 1 1
2 1 1 1
1 1 2 1
2 1 1 2
1 2 2 1
2 1 1 2
1 2 1 1
2 2 1 2
2 10 1 2
2 10 2 2
3

Sample Output

2
3
1
2
2
3
3
1
1
1
1
1
1
1 

idea:
There are 50 colors, build a line segment tree maintenance for each color, and open the point dynamically.
The first operation: change the color of the point (x, y) to c
The second: ask the number of color types between the two points (1, y1), (x, y2)
We can build a line segment tree on the y-axis, horizontal The coordinate is the value, then to determine whether there is a certain color before the two points, just ask the minimum value (that is, the abscissa) of each color between y1 and y2. Determine whether the minimum value is less than the second operation gives x, if it is less than that, it means that there is this color between the two points.

Implementation code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mid int m = (l + r) >> 1
const int M = 1e6+10;
int n = 1e6,flag=0;
int sum[M],ne=0,ls[M],rs[M],rt[100];

void update( int &k, int l, int r, int p, int num){
     if (! k){ //If the current interval is not expanded, expand and assign
        k = ++ ne;
        sum[k] = num;
    }
    sum[k] = min(sum[k],num);//The current interval has value, update the minimum value
     if (l == r)
         return ;
    mid;
    if(p <= m) update(ls[k],l,m,p,num);
    else update(rs[k],m+1,r,p,num);
}

void query(int k,int L,int R,int l,int r,int up){
    if(!k||flag) return ;
    if(L <= l&&R >= r){
        if(sum[k]<=up)
            flag = 1;
            return;
    }
    mid;
    if(L <= m) query(ls[k],L,R,l,m,up);
    if(R > m) query(rs[k],L,R,m+1,r,up);
    return ;
}

void  init(){
   memset(rt,0,sizeof(rt));
   memset(sum,0,sizeof(sum));
   memset (ls, 0 , sizeof (ls));
   memset(rs,0,sizeof(rs));
   ne = 0 ;
}
intmain ()
{
    int op,x,y,z;
    while(~scanf("%d",&op)){
        if(op == 0)
            init();
        else  if (op == 1 ) {
            scanf("%d%d%d",&x,&y,&z);
            update(rt[z],1,n,y,x);
        }
        else  if (op == 2 ) {
            scanf("%d%d%d",&x,&y,&z);
            int ans = 0 ;
            for(int i = 0;i <= 50;i ++){
                 flag = 0;
                 query(rt[i],y,z,1,n,x);
                 if(flag) ans++;
            }
            printf("%d\n",ans);
        }
        else  return  0 ;
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325356235&siteId=291194637