HDU 6183 线段树新玩法 + 离散化

来源:互联网 发布:外汇高盛软件 编辑:程序博客网 时间:2024/06/16 15:46

题目

Color it

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 872    Accepted Submission(s): 265


Problem Description
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.

0 : clear all the points.

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

2 x y1 y2 : count how many different colors in the square (1,y1) and (x,y2). That is to say, if there is a point (a,b) colored c, that 1ax and y1by2, then the color c should be counted.

3 : exit.
 

Input
The input contains many lines. 

Each line contains a operation. It may be '0', '1 x y c' ( 1x,y106,0c50 ), '2 x y1 y2' (1x,y1,y2106 ) or '3'. 

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

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

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

There are at most 10 operation 0. 

 

Output
For each operation 2, output an integer means the answer .
 

Sample Input
01 1000000 1000000 501 1000000 999999 01 1000000 999999 01 1000000 1000000 492 1000000 1000000 10000002 1000000 1 100000001 1 1 12 1 1 21 1 2 22 1 1 21 2 2 22 1 1 21 2 1 32 2 1 22 10 1 22 10 2 201 1 1 12 1 1 11 1 2 12 1 1 21 2 2 12 1 1 21 2 1 12 2 1 22 10 1 22 10 2 23
 

Sample Output
23122331111111
 
题意

  给我一个区间让我们求出这个区间内有多少个不同的颜色

解题思路
  
  第一次做用的二分TLE , 本题用的线段树,离散化的方式储存了51棵虚树 ,因为只有51个点,构建51棵树, 我们只需要维护纵坐标就可以了 , 因为横坐标固定了一个,只有一个横坐标是变化的,这样子这个题就有点像区间内求最小值的问题,只是在这里变成了区间(纵坐标的区间)内求最近的横坐标,相互转化一下就可以了,这里的离散化处理很值得学习,数据结构学的东西都还给老师了真是惭愧。

代码
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std ;const int maxn = 1000000 + 10 ;int x , y , yc , cnt , flag , root[55] , lson[maxn] , rson[maxn] , v[maxn] ;void update(int &node , int l , int r ){    int mid = (l + r) >> 1 ;    if(!node)    {        node = cnt ;        lson[node] = 0 ;        rson[node] = 0 ;        v[cnt++] = x ;    }    v[node] = min(v[node] , x) ;    if(l == r)        return ;    if(y <= mid)        update(lson[node] , l , mid ) ;    else        update(rson[node] , mid + 1 , r ) ;}void query(int node , int l , int r){    if(flag || !node)        return ;    if(y <= l && r <= yc)    {        if(v[node] <= x)            flag = 1 ;        return ;    }    int mid = (l + r) >> 1 ;    if(y <= mid)     ///愚了愚了 记错了 给写颠倒了        query(lson[node] , l , mid) ;    if(yc > mid)        query(rson[node] , mid + 1 , r) ;}int main(){    int ca ;    cnt = 1 ;    memset(root , 0 , sizeof(root)) ;    while(scanf("%d" , &ca) && ca != 3)    {        if(ca == 0) {        memset(root , 0 , sizeof(root)) ;        cnt = 1 ; continue ;         }        scanf("%d %d %d" , &x , &y , &yc) ;        if(ca == 1)        {           update(root[yc] , 1 , 1000000) ;        }        if(ca == 2)        {            int ans = 0 ;            for(int i = 0 ; i<= 50 ; i++)          {                flag = 0 ;                query(root[i] , 1 , 1000000) ;                ans += flag ;          }           printf("%d\n" , ans) ;        }    }    return 0 ;}


 

原创粉丝点击