• Codeforces983D. Arkady and Rectangles


    $n leq 100000$个矩形,一个一个覆盖在坐标系上,每个颜色都不一样,问最后能看到几种颜色。

    由于后面的颜色可以覆盖前面的颜色,可以把颜色与时间联系上,第$i$个矩形颜色$i$来把时间维变成Max,接下来就是二维操作。

    把矩形差分后按$x$排序可以得到一个y轴上的区间操作:区间加上或删除某种颜色;查区间内没统计过答案的最大的颜色(以此保证每个颜色只统计一次)。

    区间维护:啪在了这整个区间的所有颜色(集合s,用set存);最大的没统计过答案的颜色(Max值)。一个区间中s的最大值如果比孩子的Max还要大,那么要么他会成为这个区间的Max,要么这个区间里没有Max(把孩子区间里的Max啪没了)。这里注意的是每个区间只有覆盖这整个区间的颜色,没有包括他儿子的,所以会出现儿子有些颜色比父亲大的情况。如果他成为了这个区间的Max,首先他得没统计过答案,其次他得看得见,也就是不会被孩子里的所有比他大的颜色给啪没。注意他虽然是啪在这整个区间的颜色的最大值,但可能被若干子区间的比他大的颜色一起啪没,所以如果他要能露个头出来,必须大于子区间的Min--区间可见颜色中最小的一个。如果s的最大值比孩子的Max小,直接继承。每次把同个x的所有操作搞完之后,不停地取线段树根节点的Max并把这段颜色重新加入(标记了统计过答案,效果不同)。

    现在多了个Min,Min只需要看s的最大值会不会把左右孩子的Min给啪掉,如果会就是s的最大值,否则直接继承。

    俩log。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<set>
      5 #include<algorithm>
      6 //#include<math.h>
      7 //#include<iostream>
      8 //#include<time.h>
      9 using namespace std;
     10 
     11 #define LL long long
     12 int qread()
     13 {
     14     char c; int s=0,t=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (t=-1);
     15     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*t;
     16 }
     17 
     18 //Pay attention to read!
     19 
     20 int n,m;
     21 #define maxn 400011
     22 int lisax[maxn],lx=0,lisay[maxn],ly=0,ll[maxn],rr[maxn];
     23 struct MM{int x,y1,y2,ty,col;}mm[maxn]; int lm=0;
     24 bool cmpx(const MM &a,const MM &b) {return a.x<b.x;}
     25 
     26 bool vis[maxn];
     27 struct SMT
     28 {
     29     struct Node{int ls,rs,Max,Min; set<int,greater<int> > s;}a[maxn<<1];
     30     int size,n;
     31     void up(int x)
     32     {
     33         Node &b=a[x],&p=a[a[x].ls],&q=a[a[x].rs];
     34         int mm=b.s.empty()?-1:*(b.s.begin());
     35         if (mm>max(p.Max,q.Max))
     36         {
     37             if (vis[mm]) b.Max=-1;
     38             else if (mm<min(p.Min,q.Min)) b.Max=-1;
     39             else b.Max=mm;
     40         }
     41         else b.Max=max(p.Max,q.Max);
     42         b.Min=max(mm,min(p.Min,q.Min));
     43     }
     44     void build(int &x,int L,int R)
     45     {
     46         x=++size; a[x].Max=-1; a[x].Min=-1;
     47         if (L==R) return;
     48         int mid=(L+R)>>1;
     49         build(a[x].ls,L,mid); build(a[x].rs,mid+1,R);
     50     }
     51     void clear(int N) {size=0; n=N; a[0].Max=a[0].Min=-1; int x; build(x,1,n);}
     52     int ql,qr,v;
     53     void Add(int x,int L,int R)
     54     {
     55         if (ql<=L && R<=qr) {if (!vis[v]) a[x].s.insert(v); up(x); return;}
     56         int mid=(L+R)>>1;
     57         if (ql<=mid) Add(a[x].ls,L,mid);
     58         if (qr> mid) Add(a[x].rs,mid+1,R);
     59         up(x);
     60     }
     61     void add(int L,int R,int V) {ql=L; qr=R; v=V; Add(1,1,n);}
     62     void DEL(int x,int L,int R)
     63     {
     64         if (ql<=L && R<=qr) {a[x].s.erase(v); up(x); return;}
     65         int mid=(L+R)>>1;
     66         if (ql<=mid) DEL(a[x].ls,L,mid);
     67         if (qr> mid) DEL(a[x].rs,mid+1,R);
     68         up(x);
     69     }
     70     void Del(int L,int R,int V) {ql=L; qr=R; v=V; DEL(1,1,n);}
     71 }t;
     72 
     73 int main()
     74 {
     75     m=qread();
     76     for (int i=1,x1,x2;i<=m;i++)
     77     {
     78         x1=qread(); lm++; mm[lm].y1=qread(); x2=qread(); mm[lm].y2=qread();
     79         mm[lm].x=x1; mm[lm].ty=1; mm[lm+1]=mm[lm]; lm++; mm[lm].x=x2; mm[lm].ty=-1;
     80         lisax[++lx]=x1; lisax[++lx]=x2; lisay[++ly]=mm[lm].y1; lisay[++ly]=mm[lm].y2;
     81         mm[lm].col=mm[lm-1].col=i;
     82     }
     83     
     84     sort(lisax+1,lisax+1+lx); sort(lisay+1,lisay+1+ly);
     85     lx=unique(lisax+1,lisax+1+lx)-lisax-1; ly=unique(lisay+1,lisay+1+ly)-lisay-1;
     86     for (int i=1;i<=lm;i++) mm[i].x=lower_bound(lisax+1,lisax+1+lx,mm[i].x)-lisax,
     87     mm[i].y1=lower_bound(lisay+1,lisay+1+ly,mm[i].y1)-lisay,
     88     mm[i].y2=lower_bound(lisay+1,lisay+1+ly,mm[i].y2)-lisay;
     89     for (int i=1;i<=m;i++) ll[i]=mm[i<<1].y1,rr[i]=mm[i<<1].y2;
     90     
     91     t.clear(ly);
     92     sort(mm+1,mm+1+lm,cmpx);
     93     int ans=0;
     94     for (int i=1,j=1;i<=lx;i++)
     95     {
     96         for (;j<=lm && mm[j].x==i;j++)
     97         {
     98             if (mm[j].ty==1) t.add(mm[j].y1,mm[j].y2-1,mm[j].col);
     99             else t.Del(mm[j].y1,mm[j].y2-1,mm[j].col);
    100         }
    101         int tmp=t.a[1].Max;
    102         while (~tmp)
    103         {
    104             vis[tmp]=1; ans++; t.add(ll[tmp],rr[tmp]-1,tmp);
    105             tmp=t.a[1].Max;
    106         }
    107     }
    108     printf("%d
    ",ans+1);
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    单机安装hadoop+hive+presto
    java ListMap使用多个key比较
    java多线程-3-使用多线程的时机
    java多线程-2-概念和实现机制
    mysql的varchar和oracle的varchar2比较
    js-对象创建
    java关于json的一些问题
    spring使用RedisCacheManager管理key的一些问题
    如何提高工作效率
    关系数据库之-事务
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9066936.html
Copyright © 2020-2023  润新知