zoukankan      html  css  js  c++  java
  • zoj 2301 || hdu 1199 Color the Ball 线段树 离散化

    题目链接:

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1301

    题意:

    [l,r],染成w/b, 初始全为b,问最长段的w

    题解:

    因为N小于2000,染色范围可以到2^31,所以要离散化

    http://blog.csdn.net/zxy_snow/article/details/6639878
    其实这题的意思是 染色区间【闭区间】,而不是点,但是我们把r往右移一个格就转化为点了。
    这里写图片描述
    给一组数据,应该输出1 5
    2
    1 3 w
    4 5 w
    更新的是点,使右边加一,就变成连续的区间了。否则就更新不上去1~5这整块区间了
    这里写图片描述

    代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 #define MS(a) memset(a,0,sizeof(a))
      5 #define MP make_pair
      6 #define PB push_back
      7 const int INF = 0x3f3f3f3f;
      8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
      9 inline ll read(){
     10     ll x=0,f=1;char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return x*f;
     14 }
     15 //////////////////////////////////////////////////////////////////////////
     16 const int maxn = 4010+10;
     17 
     18 int x[maxn],y[maxn],c[maxn],tmp[2*maxn],vis[maxn];
     19 int cnt;
     20 char ch;
     21 
     22 struct node{
     23     int l,r,col;
     24 }t[maxn<<2];
     25 
     26 void build(int rt,int l,int r){
     27     if(l >= r) return ;
     28     t[rt].l=l,t[rt].r=r,t[rt].col=0;
     29     if(l == r-1) return ;
     30     int mid = (l+r)/2;
     31     build(rt<<1,l,mid);
     32     build(rt<<1|1,mid,r);
     33 }
     34 
     35 void update(int rt,int l,int r,int c){
     36     if(l >= r) return ;
     37     int L=t[rt].l,R=t[rt].r;
     38     if(l<=L && R<=r){
     39         // cout << rt << " " << l << " " << r << " " << L << " " << R << " uuu
    ";
     40         t[rt].col = c;
     41         return ;
     42     }
     43     if(t[rt].col>=0 && t[rt].col!=c){
     44         t[rt<<1].col=t[rt<<1|1].col = t[rt].col;
     45         t[rt].col = -1;
     46     }
     47 
     48     int mid = (L+R)/2;
     49     if( l >= mid )  
     50         update(rt<<1|1,l,r,c);
     51     else  
     52         if( r <= mid )  
     53             update(rt<<1,l,r,c); 
     54         else  
     55         {  
     56             update(rt<<1,l,mid,c);
     57             update(rt<<1|1,mid,r,c);
     58         }  
     59 }
     60 
     61 void query(int rt){
     62     int L=t[rt].l,R=t[rt].r;
     63     if(t[rt].col >= 0){
     64         // cout << rt << " " << L << " " << R << endl;
     65         for(int i=L; i<R; i++)
     66             vis[i] = t[rt].col;
     67         return ;
     68     }
     69 
     70     if(L == R) return ;
     71     query(rt<<1);
     72     query(rt<<1|1);
     73 }
     74 
     75 int main(){
     76     int n;
     77     while(cin>>n){
     78         cnt = 0;
     79         MS(x);MS(y);MS(c);MS(tmp);
     80         for(int i=0; i<n; i++){
     81             scanf("%d%d %c",&x[i],&y[i],&ch);
     82             y[i]++; // 2
     83                     // 1 3 w
     84                     // 4 5 w  更新的是点,使右边加一,就变成连续的区间了。否则就更新不上去1~5这整块区间了
     85             tmp[cnt++] = x[i];
     86             tmp[cnt++] = y[i];
     87             if(ch == 'w') c[i] = 1;
     88         }
     89         sort(tmp,tmp+cnt);
     90         cnt = unique(tmp,tmp+cnt)-tmp;
     91 
     92         build(1,0,cnt);
     93 
     94         for(int i=0; i<n; i++){
     95             int p1,p2;
     96             p1 = lower_bound(tmp,tmp+cnt,x[i])-tmp;
     97             p2 = lower_bound(tmp,tmp+cnt,y[i])-tmp;
     98             update(1,p1,p2,c[i]);
     99         }
    100 
    101 
    102         memset(vis,0,sizeof(vis));
    103         query(1);
    104         // cout << t[1].col << "  ppp
    ";
    105         // for(int i=0; i<cnt; i++)
    106         //  cout << tmp[i] << " ";
    107         // cout << endl;
    108 
    109         tmp[cnt] = tmp[cnt-1];
    110         int s=0,e=0,ts,te;
    111 
    112         for(int i=0; i<cnt; i++){  
    113             if( vis[i] != 1 ) continue;  
    114             ts = tmp[i];  
    115             while( vis[i] == 1 )  // 查询使得[L,R)的vis变为1, 在R的位置也是符合的,但是不赋值为1,所以跳出循环时候的i也是符合的
    116                 i++;  
    117             if( i > cnt ) break;  
    118             te = tmp[i];  
    119             if( te - ts > e - s ) {  
    120                 e = te;  
    121                 s = ts;  
    122             }  
    123         }  
    124     if( s == e )  
    125         printf("Oh, my god
    ");  
    126     else  
    127         printf("%d %d
    ",s,e-1);  
    128     }
    129 
    130     return 0;
    131 }
  • 相关阅读:
    Python 7步机器学习
    STL容器-- map and multimap 用法
    STL容器-- forward_list 用法
    STL容器-- fixed-size array 用法
    STL容器-- deque 用法
    网站502与504错误分析
    git将一个分支的某个文件合并到当前分支
    阿里云RDS上用mysqldump导入导出
    mysqldump具体应用实例
    mysql的导入导出工具mysqldump命令详解
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827565.html
Copyright © 2011-2022 走看看