牛客小白月赛61 F 尺取法 前缀和

题目的描述是多维的 即有人数限制又有座位限制。

但是每次选座位是连续的,这意味着可以利用尺取法贪心的求出以每个左端点为起始最小的合法的右端点。

考虑如何求f(x) 即x人来满足的方案数 考虑一个区间 L,R可行那么 L-1,R也必然可行。

所以当前的L,R向左延申完全重复,只能向右延申可以发现延申至n这些方案均没有重复。

这样我们得到的方案是以每个左端点为起始的互不相同的方案可以发现覆盖所有情况。

code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 2000000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define l(x) s[x].l
#define r(x) s[x].r
#define S second
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
using namespace std;
const int MAXN=100010;
int len,n,m,sum;
int cnt[MAXN],w[MAXN];
int lin[MAXN],ver[MAXN],nex[MAXN];
inline void add(int x,int y)
{
	ver[++len]=y;
	nex[len]=lin[x];
	lin[x]=len;
}
inline void add1(int x)
{
	go(x)
	{
		++w[tn];
		if(w[tn]==1)++sum;
	}
}
inline void sub(int x)
{
	go(x)
	{
		--w[tn];
		if(!w[tn])--sum;
	}
}
int main()
{
	freopen("1.in","r",stdin);
	sc(n);sc(m);
	rep(1,m,i){int x;sc(x);add(x,i);}
	rep(1,m,i){int x;sc(x);add(x,i);}
	rep(1,m,i){int x;sc(x);add(x,i);}
	int R=0;
	for(int L=1;L<=n;++L)
	{
		while(sum!=m&&R<n)
		{
			++R;add1(R);
		}
		if(sum==m)++cnt[R-L+1],--cnt[R-L+1+n-R+1];
		sub(L);
	}
	rep(1,n,i)cnt[i]=(cnt[i]+cnt[i-1])%mod;
	int ans=0,w=1;
	rep(1,n,i)
	{
		w=(ll)w*i%mod;
		put_((ll)cnt[i]*w%mod);
	}
	return 0;
}
posted @ 2022-11-21 10:37  chdy  阅读(47)  评论(0编辑  收藏  举报