• bzoj1178/luogu3626 会议中心 (倍增+STL::set)


    贪心地,可以建出一棵树,每个区间对应一个点,它的父亲是它右边的、与它不相交的、右端点最小的区间。

    为了方便,再加入一个[0,0]区间

    于是就可以倍增来做出从某个区间开始,一直到某个右界,这之中最多能选多少区间

    这样的话,可以从[0,0]区间,倍增做出第一问的答案

    考虑第二问,我们需要尽量选编号小的区间,于是只要判断我们如果选了这个区间 还能不能选够那么多就可以了

    而且前面已经选过的就钦定住了

    开一个set来放下已经选过的区间,按左端点从小到大排序

    为了方便,一开始先把[0,0]区间和[inf,inf]区间加进去。设当前区间是x

    这样的话,只要找到前驱pre、后继nxt,判断pre、nxt是否和x相交,相交就不做了

    然后看从pre到nxt能选几个、(pre到x)+(x到nxt)+1能选几个,看看是否相等,来判断选不选x

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=2e5+10,inf=1e9+1;
     7 
     8 inline ll rd(){
     9     ll x=0;char c=getchar();int neg=1;
    10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    12     return x*neg;
    13 }
    14 
    15 struct Node{
    16     int l,r,i;
    17     Node (int a=0,int b=0,int c=0){l=a,r=b,i=c;}
    18 }pos[maxn],pos2[maxn],pos3[maxn];
    19 bool operator < (Node a,Node b){return a.l<b.l;}
    20 int N,M;
    21 int ma[maxn*2],fa[maxn][20],cnt[maxn][20];
    22 set<Node> st;
    23 bool flag[maxn];
    24 
    25 inline bool cmp(Node a,Node b){return a.l<b.l;}
    26 inline bool cmp2(Node a,Node b){return a.r<b.r;}
    27 
    28 inline int getst(int x,int bnd){
    29     int re=0;
    30     for(int i=18;i>=0;i--){
    31         if(fa[x][i]&&pos2[fa[x][i]].r<bnd)
    32             re+=cnt[x][i],x=fa[x][i];
    33     }
    34     return re;
    35 }
    36 
    37 int main(){
    38     //freopen("","r",stdin);
    39     int i,j,k;
    40     N=rd();
    41     for(i=1,j=0;i<=N;i++){
    42         pos[i].l=rd(),pos[i].r=rd();pos[i].i=i;
    43     }
    44     memcpy(pos2,pos,sizeof(pos));
    45     memcpy(pos3,pos,sizeof(pos));
    46     sort(pos+1,pos+N+1,cmp);
    47     sort(pos3+1,pos3+N+1,cmp2);
    48     int mm=inf,mi=0;
    49     for(i=N,j=N;i;i--){
    50         for(;pos[j].l>pos3[i].r;j--){
    51             if(pos[j].r<mm) mm=pos[j].r,mi=pos[j].i;
    52         }
    53         int x=pos3[i].i;
    54         fa[x][0]=mi;cnt[x][0]=1;
    55         // printf("%d %d
    ",x,fa[x][0]);
    56         for(k=0;fa[x][k]&&fa[fa[x][k]][k];k++){
    57             fa[x][k+1]=fa[fa[x][k]][k];
    58             cnt[x][k+1]=cnt[x][k]+cnt[fa[x][k]][k];
    59         }
    60     }
    61     fa[N+1][0]=pos3[1].i;cnt[N+1][0]=1;
    62     for(k=0;fa[N+1][k]&&fa[fa[N+1][k]][k];k++){
    63         fa[N+1][k+1]=fa[fa[N+1][k]][k];
    64         cnt[N+1][k+1]=cnt[N+1][k]+cnt[fa[N+1][k]][k];
    65     }
    66     printf("%d
    ",getst(N+1,inf));
    67     
    68     st.insert(Node(0,0,N+1));st.insert(Node(inf,inf,N+2));
    69     for(i=1;i<=N;i++){
    70         set<Node>::iterator it=st.lower_bound(pos2[i]);
    71         Node nxt=*it;
    72         Node pre=*(--it);
    73         if(nxt.l<=pos2[i].r||pre.r>=pos2[i].l) continue;
    74         int n1=getst(pre.i,pos2[i].l)+getst(i,nxt.l)+1;
    75         int nn=getst(pre.i,nxt.l);
    76         // printf("%d %d %d %d %d
    ",i,pre.i,nxt.i,nn,n1);
    77         if(n1<nn) continue;
    78         flag[i]=1;
    79         st.insert(pos2[i]);
    80     }
    81     for(i=1;i<=N;i++) if(flag[i]) printf("%d ",i);
    82     return 0;
    83 }
  • 相关阅读:
    理解SVG坐标系统和变换: transform属性
    在svg文间画图过程中放大缩小图片后,坐标偏移问题
    理解SVG的缩放 偏移的计算公式
    svg 实践之屏幕坐标与svg元素坐标转换
    Winform 程序打包及安装
    使用bootstrap table小记(表格组件)
    MVC实现多级联动
    微信公众号开发之网页中及时获取当前用户Openid及注意事项
    微信公众号开发之网页授权获取用户基本信息
    微信公众号开发之自动消息回复和自定义菜单
  • 原文地址:https://www.cnblogs.com/Ressed/p/9759688.html
Copyright © 2020-2023  润新知