首页 > 其他分享 >[CF1965F] conference

[CF1965F] conference

时间:2024-12-22 21:08:23浏览次数:9  
标签:conference 满足条件 int nc CF1965F define 讲师 getchar

题意:有 \(n\) 个讲师,对于讲师 \(i\),他可以在 \([l_i,r_i]\) 中选一天讲课,问对于 \(x \in [1,n]\),有多少连续的 \(x\) 天可以做到都有讲师讲课。

先考虑区间的 \(l\) 互不相同时如何解决。

对于已知的 \([l,r]\) 是否存在完美匹配,判断是简单的,我们贪心地按天数从左往右依次解决,每次填覆盖当前天的 \(r\) 最小的讲师即可。

根据 hall 定理,我们发现若 \([l,r]\) 满足条件,那么 \([nl,nr] \subseteq [l,r]\) 必然满足条件,所以我们只需要判断 \([l,r]\) 是否满足条件即可。

然后我们从后往前扫求对于第 \(i\) 天,符合条件的最大的 \(R_i\) 在哪里就行了,这个根据上面的贪心处理即可。

那么对于区间 \(l\) 有相同的其实差不多,若区间 \([l,r]\) 被分配给了第 \(d\) 天,那这个区间可以被写成 \([d,r]\),然后就和区间的 \(l\) 互不相同的时候一样了。

点击查看代码
#include<bits/stdc++.h>
#define fir first
#define sec second
#define int long long
#define lowbit(x) x&(-x)
#define mkp(a,b) make_pair(a,b)
using namespace std;
typedef pair<int,int> pir;
inline int read(){
	int x=0,f=1; char c=getchar();
	while(!isdigit(c)){if(c=='-') f=-1; c=getchar();}
	while(isdigit(c)){x=x*10+(c^48); c=getchar();}
	return x*f;
}
const int inf=1e9,N=2e5+5;
int n,m;
vector<int> ed[N];
multiset<int> s;
int c[N],nc[N],op[N],pos[N],res[N];
signed main(){
    n=read();
    for(int i=1;i<=n;i++){
        int l=read(),r=read();
        ed[l].push_back(r);
        m=max(m,r);
    }
    for(int i=1;i<=m;i++){
        for(auto r:ed[i]) s.insert(r);
        while(s.size()&&*s.begin()<i) s.erase(s.begin());
        if(s.size()){
            int r=*s.begin();
            s.erase(s.begin());
            c[i]++,c[r+1]--;
            op[i]=1;
        }
        else nc[i]++;
    }
    for(int i=1;i<=m;i++) nc[i]+=nc[i-1],c[i]+=c[i-1];
    int r=m+1;
    for(int i=m;i>=1;i--){
        int num=c[i]-op[i]+1+nc[i-1];
        pos[nc[i]]=i;
        if(num<=m&&pos[num]) r=min(r,pos[num]);
        res[r-i]++;
    }
    for(int i=n;i;i--) res[i]+=res[i+1];
    for(int i=1;i<=n;i++) cout<<res[i]<<'\n';
}

标签:conference,满足条件,int,nc,CF1965F,define,讲师,getchar
From: https://www.cnblogs.com/Cyan0826/p/18622534

相关文章