【题解】方块染色(容斥原理+巧妙分类)

【题解】方块染色(容斥原理+巧妙分类)

刚开始以为是道容斥,写了这个错误程序


int main(){
      pre(1e5);
      while(~scanf("%d%d",&n,&m)){
	    int ans=0;
	    for(register int t=m,delta;t<=n;++t){
		  delta=0;
		  for(register int k=1,d2;k<=n/t;++k){
			d2=1ll*c(n/t,k)*(n-k*t+1)%mod*bin[n-k*t]%mod;
			if(k&1) d2=mod-d2;
			delta+=d2;
			while(delta>=mod)delta-=mod;
		  }
		  if((t-m)&1) delta=mod-delta;
		  ans=(ans+delta)%mod;
	    }
	    printf("%d\n",ans);
      }
      return 0;
}

这显然是错的,容斥套容斥,我不知道为什么我敢交上去(可能是对了样例)

后来我通过仔(bai)细(du)思(ti)考(jie)获得了启示

\(dp(n)\)\(n\)个时的方案数

假如我已经知道前面\(n-1\)的方案,现在要知道\(n\)的方案了,怎么做?

显然地,肯定有一个\(2dp(n-1)\)的贡献,意思是在后面加上一个块,什么颜色无所谓

然后我通过思(ti)考(jie)发现,可以这样分类:

  • 加上去的没有作用,加不加这一块对于满足合法条件没有贡献,直接加就好了,什么颜色无所谓,所以就是\(2dp(n-1)\)

  • 加上去的有作用,那就是说,整个序列只有后缀的\(m\)个元素有用,其他都是打酱油,那么先钦定后面\(m\)个都是红色,现在问题就是前面\(n-m\)个要求不能产生作用,这样才能满足我们这里的分类。

    那么就是总数-不合法呗,但是且慢,假如说我前面\(n-m\)个和后面这个\(m\)个连接在一起了,就会和加上去没有作用的那个分类重复。所以我要钦定倒数第\(m+1\)是蓝色,所以前面总共有\(2^{n-m-1}-dp(n-m-1)\)有贡献了。

    你可能会问,那可能存在一种合法方案,使得是倒数\(m+x\)个使得整个序列满足条件啊,这种方案去哪了? 这种方案被放在了第一个分类中,因为这样的话,最后一个块什么颜色就无所谓了,少了不会使得整个序列不满足条件。

所以直接递推:

\[dp(x)=2dp(x-1)+2^{x-m-1}-dp(x-m-1) \]

初始条件\(dp(m)=1\)

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;  typedef long long ll;
inline int qr(){
      register int ret=0,f=0;
      register char c=getchar();
      while(c<48||c>57)f|=c==45,c=getchar();
      while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
      return f?-ret:ret;
}
const int maxn=1e5+5;
const int mod=1e9+7;
int bin[maxn],dp[maxn];
int n,m;

int main(){
      for(register int t=bin[0]=1;t<=100000;++t){
	    bin[t]=bin[t-1]<<1;
	    while(bin[t]>=mod) bin[t]-=mod;
      }
      while(~scanf("%d%d",&n,&m)){
	    dp[m]=1;
	    for(register int t=m+1;t<=n;++t){
		  dp[t]=dp[t-1]<<1;
		  while(dp[t]>mod) dp[t]-=mod;
		  dp[t]+=bin[t-m-1];
		  while(dp[t]>mod) dp[t]-=mod;
		  if(t-m-1>=m) dp[t]+=mod-dp[t-m-1];
		  while(dp[t]>mod) dp[t]-=mod;
	    }
	    printf("%d\n",dp[n]);
      }
      return 0;
}


posted @ 2019-08-26 22:25  谁是鸽王  阅读(359)  评论(0编辑  收藏  举报