zoukankan      html  css  js  c++  java
  • CF983D Arkady and Rectangles

    题意:给你若干个不同色的矩形。问依次覆盖,最后留在平面上的有多少种颜色(要加上空白)?

    n<=100000.

    标程:

     1 #include<bits/stdc++.h>
     2 #define fir first
     3 #define sec second
     4 #define P pair<int,int>
     5 using namespace std;
     6 int read()
     7 {
     8    int x=0,f=1;char ch=getchar();
     9    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    10    while (ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    11    return x*f;
    12 }
    13 const int N=200005;
    14 set<int> s[N<<2]; 
    15 vector<P> vec[N];
    16 int Max[N<<2],Min[N<<2],vis[N],a[N],b[N],c[N],d[N],px[N],py[N],ans,tmp,n;
    17 void up(int k,int l,int r)
    18 {
    19     if (l==r) Max[k]=Min[k]=0;
    20     else Max[k]=max(Max[k<<1],Max[k<<1|1]),Min[k]=min(Min[k<<1],Min[k<<1|1]);//统计子节点
    21     if ((int)s[k].size())//统计这个节点的覆盖
    22     {
    23         if (vis[tmp=*s[k].rbegin()]) Min[k]=max(Min[k],tmp);
    24         else Max[k]=max(Max[k],tmp);
    25     }
    26     if (Max[k]<Min[k]) Max[k]=0;
    27 }
    28 void ins(int k,int l,int r,int L,int R,int x)
    29 {
    30     if (L<=l&&r<=R)
    31     {
    32         if (x)
    33           if (x>0) s[k].insert(x);else s[k].erase(-x);
    34         up(k,l,r);
    35         return;
    36     }
    37     int mid=(l+r)>>1;
    38     if (L<=mid) ins(k<<1,l,mid,L,R,x);
    39     if (R>mid) ins(k<<1|1,mid+1,r,L,R,x);
    40     up(k,l,r);
    41 }
    42 int main()
    43 {
    44    n=read();
    45    for (int i=1;i<=n;i++) a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read(),px[++*px]=a[i],px[++*px]=c[i],py[++*py]=b[i],py[++*py]=d[i];
    46    sort(px+1,px+*px+1);sort(py+1,py+*py+1);
    47    *px=unique(px+1,px+*px+1)-px-1;
    48    *py=unique(py+1,py+*py+1)-py-1;
    49    for (int i=1;i<=n;i++)
    50    {
    51        a[i]=lower_bound(px+1,px+*px+1,a[i])-px;
    52        c[i]=lower_bound(px+1,px+*px+1,c[i])-px;
    53        b[i]=lower_bound(py+1,py+*py+1,b[i])-py;
    54        d[i]=lower_bound(py+1,py+*py+1,d[i])-py-1;
    55        vec[a[i]].push_back(P(i,i));
    56        vec[c[i]].push_back(P(i,-i));
    57     }
    58    for (int i=1;i<=*px;i++)
    59    {
    60        for (int j=0;j<vec[i].size();j++) ins(1,1,*py,b[vec[i][j].fir],d[vec[i][j].fir],vec[i][j].sec);
    61        while (Max[1])
    62        {
    63            vis[Max[1]]=1;ans++;
    64            ins(1,1,*py,b[Max[1]],d[Max[1]],0);
    65         }
    66     }
    67     printf("%d
    ",ans+1);
    68    return 0;
    69 }

    易错点:1.对端点离散化的时候注意直接离散,不要先把d[i]-1。离散化寻址的时候再找前一个。(不然会错)

    即是把边染色转换成点染色。

    题解:线段树+set+技巧神题

    很容易想到扫描线,问题是:1.如何不重复地统计出现过的颜色,2.如何用线段树快速维护颜色层的覆盖。

    问题1用一个vis数组打标记,问题2对于线段树的每一个节点维护一个set,表示完全覆盖这个节点的颜色。

    对于每一个节点所表示区间露出来的颜色,用Min表示统计过的最小覆盖颜色。Max表示未统计过最大覆盖颜色。(有性质Min和Max只有其一有值)

    每次取Max[1]统计答案,并在线段树中消除该颜色的贡献。

  • 相关阅读:
    业务领域建模Domain Modeling
    用例建模Use Case Modeling
    分析一套源代码的代码规范和风格并讨论如何改进优化代码
    结合工程实践选题调研分析同类软件产品
    如何提高程序员的键盘使用效率
    python知识准备及环境配置
    一张图片在Python操作下的4种玩法(附源码)
    Python中的错误和异常
    当你忘记网站上的密码时怎么办?Python如何快速帮你找回?
    Python最简单的图片爬虫,20行代码带你爬遍整个网站
  • 原文地址:https://www.cnblogs.com/Scx117/p/9069339.html
Copyright © 2011-2022 走看看