• 【题解】[APIO2009]会议中心


    【题解】[P3626 APIO2009]会议中心

    真的是一道好题!!!刷新了我对倍增浅显的认识。

    此题若没有第二份输出一个字典序的方案,就是一道(sort+)贪心,但是第二问使得我们要用另外的办法。

    考虑到题目的性质,贪心地想,假如我们已经选择了区间(i),我们就可以盖将自其变者而观之,则天地曾不能以一瞬;自其不变者而观之,则物与我皆无尽也,而又何羡乎!确定下一个是谁,虽世殊事异,所以兴怀,其致一也,而且不用关心其他的情况,也就是说,下一个选择是确定的!

    考虑暴力存下来我是下(i)个是谁,空间不够,怎么办?考虑到,我附庸的附庸也是我的附庸下一个的下一个是我的下两个,可以倍增啊!

    (st(i,j))表示选择(i)后,下(2^j)选择是谁。可以先预处理(k=0),然后直接倍增的套路把数组处理出来。

    那么如何确定答案呢?

    我们对于线段建立一个拟阵((L,E)),易知对于答案线段集合(e in E)是显然满足遗传性和增广性的,那只还在集族(E)中,仍然是独立集,就一定是这个拟阵中极大独立集的一个。那么我们就可以(O(nlogn+nf(x)))地确定极大独立集了。

    哈哈哈哈哈哈

    就是贪心,没有别的。

    我们搞个这样的操作:假若加入我这个答案,发现被我影响的所有区间内的总答案没有发生变化,那么我们就加吧。然后按照加入的时间顺序加,就直接可以输出了。

    开眼了!

    暴露了一个问题,我平衡树一个都不会,必须学一个QAQ

    #include<bits/stdc++.h>
    
    using namespace std;typedef long long ll;
    #define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
    #define RP(t,a,b)  for(register int t=(a),edd=(b);t<=edd;++t)
    #define ERP(t,a)   for(register int t=head[a];t;t=e[t].nx)
    #define midd register int mid=(l+r)>>1
    #define TMP template < class ccf >
    TMP inline ccf qr(ccf b){
        register char c=getchar();register int q=1;register ccf x=0;
        while(c<48||c>57)q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
        return q==-1?-x:x;}
    TMP inline ccf Max(ccf a,ccf b){return a<b?b:a;}
    TMP inline ccf Min(ccf a,ccf b){return a<b?a:b;}
    TMP inline ccf Max(ccf a,ccf b,ccf c){return Max(a,Max(b,c));}
    TMP inline ccf Min(ccf a,ccf b,ccf c){return Min(a,Min(b,c));}
    TMP inline ccf READ(ccf* _arr,int _n){RP(t,1,_n)_arr[t]=qr((ccf)1);}
    //----------------------template&IO---------------------------
    
    const int maxn=2e5+15;
    struct DATA{
        int l,r;
        inline bool operator <(DATA x)const{return r==x.r?l>x.l:r<x.r;}
        inline DATA scan(){l=qr(1),r=qr(1);return *this;}
    }data[maxn],usd[maxn],orzpsj[maxn];
    set < DATA > qaq;
    int L[maxn],R[maxn];
    int st[maxn][33];
    int n,cnt;
    const int inf=0x3f3f3f3f;
    inline int wk(int l,int r){
        register int ret=0,now=lower_bound(L+1,L+1+cnt,l)-L;
        if(R[now]>r||now>cnt) return 0;
        DRP(t,31,0)if(st[now][t]&&R[st[now][t]]<=r)ret+=1<<t,now=st[now][t];return ret+1;
    }
    
    inline DATA mk(int l,int r){
        DATA ret;
        ret.l=l;ret.r=r;
        return ret;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("interval10.in","r",stdin);
        freopen("interval.out","w",stdout);
    #endif
        n=qr(1);
        RP(t,1,n) orzpsj[t]=data[t].scan();
        sort(data+1,data+n+1);
        RP(t,1,n) if(!cnt||data[t].l>usd[cnt].l) usd[++cnt]=data[t];
        RP(t,1,cnt) L[t]=usd[t].l,R[t]=usd[t].r;
        for(register int t=1,j=1;t<=cnt;++t){
    	while(j<=cnt&&usd[j].l<=usd[t].r) ++j;
    	if(j<=cnt) st[t][0]=j;
        }
        RP(t,1,31)
    	RP(i,1,cnt)
    	st[i][t]=st[st[i][t-1]][t-1];
        int ans=wk(-inf,inf);
        cout<<ans<<endl;
        qaq.insert(mk(inf,inf));  
        qaq.insert(mk(-inf,-inf));
        set< DATA >::iterator x,y;
        int l1,r1,l2,r2;
        RP(t,1,n) data[t]=orzpsj[t];
        RP(t,1,n){
    	y=x=qaq.lower_bound(data[t]);y--;
    	l1=y->r,r1=data[t].l,l2=data[t].r,r2=x->l;
    	if(l1>=r1||l2>=r2) continue;
    	if(wk(l1+1,r2-1)==wk(l1+1,r1-1)+wk(l2+1,r2-1+1)+1){
    	    cout<<t<<' ';qaq.insert(data[t]);
    	}
        }
        return 0;
    }
    
    
  • 相关阅读:
    Android复习(五)设备兼容—>多apk支持
    Android复习(五)设备兼容—>支持刘海屏
    KVC给只读属性进行赋值..
    pods 终端安装 第三方框架的一些命令
    使用SnakeKit怎么设置动画效果 以及 UIView的弹簧动画效果
    Cocoa、Foundation、UIKit、Objective-c、XCode、Interface Builder的概念
    仿写SDWebImage中的一个网络加载图片的框架
    TCP/IP 短链接 长链接 scoket
    init 和 initWithFrame 区别
    JSON XML 数据解析
  • 原文地址:https://www.cnblogs.com/winlere/p/10375438.html
Copyright © 2020-2023  润新知