zoukankan      html  css  js  c++  java
  • APIO2009 会议中心

    洛谷3626传送门

    Description:

    给定一些区间,求最多不相交的区间数,并且输出字典序最小的选择方案

    Solution:   f(l,r)表示[l,r]中的最多不相交的区间数

    这题好难啊 好难想也好难写qwq 然后这里的solution写得有点语无伦次了

    最多不相交的区间数贪心很好求

    直接求字典序最小的方案好像不太可行 如果我们按字典序枚举并且判断是否可以加入答案就好了

    其实就是这样的啊(强行带入)

    我们现在要想怎么判断某区间是否可以加入答案

    如图,有一些区间,现在我们要判断红色区间是否可以加入答案

    找到红色区间左边第一个和右边第一个与它不相交的区间

    如果f(r1+1,l3-1)==f(r1+1,l2-1)+f(r2+1,l3-1)+1即可以加入答案

    发现我们需要频繁的求解f(l,r)

    所以如果再像以前那样朴素地求肯定不行

    我们可以优化一下 以前我们排序后一个个枚举其实就是为了找到下一个与当前选择不相交的区间

    而这样的下一个是确定的 于是就用倍增啦 f[i][j]表示i后面的第2j个区间的编号

    最后还要注意一点

    对于下图这种情况 求最多不相交区间数时明显选择1区间比2区间优 于是我们要把2区间去掉

    所以有了code里的b[]

    CODE:

     1 #include<bits/stdc++.h>
     2 #define rg register
     3 #define go(i,a,b) for(rg int i=a;i<=b;++i)
     4 #define yes(i,a,b) for(rg int i=a;i>=b;--i)
     5 #define inf 1e9
     6 #define il inline
     7 using namespace std;
     8 int rd()
     9 {
    10     int x=0,y=1;char c=getchar();
    11     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    12     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    13     return x*y;
    14 }
    15 const int N=500005;
    16 struct node
    17 {
    18     int l,r;
    19     il bool operator <(node x)const
    20     {return r==x.r?l>x.l:r<x.r;}
    21 }a[N],b[N],c[N];
    22 int ans,n,ct,f[N][20],L[N],R[N];
    23 il int calc(int l,int r)
    24 {
    25     rg int sm=1,nw=lower_bound(L+1,L+ct+1,l)-L;
    26     if(nw>ct||R[nw]>r)return 0;
    27     yes(i,19,0)if(f[nw][i]&&R[f[nw][i]]<=r)nw=f[nw][i],sm+=1<<i;
    28     return sm;
    29 }
    30 set<node> q;
    31 int main()
    32 {
    33     freopen("1.in","r",stdin);
    34     freopen("1.out","w",stdout);
    35     n=rd();go(i,1,n)a[i].l=rd(),a[i].r=rd(),c[i]=a[i];
    36     sort(a+1,a+n+1);
    37     go(i,1,n)if(!ct||a[i].l>b[ct].l)b[++ct]=a[i];
    38     go(i,1,ct)
    39     {
    40         int j=i;
    41         while(b[j].l<=b[i].r&&j<=ct) j++;if(j>ct)continue;
    42         f[i][0]=j;
    43     }
    44     go(j,1,19)
    45         go(i,1,ct)f[i][j]=f[f[i][j-1]][j-1];
    46     go(i,1,ct)L[i]=b[i].l,R[i]=b[i].r;
    47     ans=calc(0,inf);printf("%d
    ",ans);
    48     set<node>:: iterator x,y;
    49     q.insert((node){0,0});q.insert((node){inf,inf});
    50     go(i,1,n)a[i]=c[i];
    51     go(i,1,n)
    52     {
    53         x=y=q.lower_bound(a[i]);x--;
    54         rg int l=x->r,r=y->l;
    55         if(l>=a[i].l||r<=a[i].r)continue;
    56         if(calc(l+1,r-1)==calc(l+1,a[i].l-1)+calc(a[i].r+1,r-1)+1)
    57         {printf("%d ",i);q.insert(a[i]);}
    58     }
    59     return 0;
    60 }
    View Code
    光伴随的阴影
  • 相关阅读:
    elementui组件库eldialog弹出框被遮罩层挡住
    python常规基础操作
    python中的字典排序
    python列表面试题
    python logging日志模块
    python序列之列表
    jmeter中csv连接数据库
    python必会的知识基础
    jmeter tcp 压力测试
    python模块基础知识练习
  • 原文地址:https://www.cnblogs.com/forward777/p/10383868.html
Copyright © 2011-2022 走看看