【补题日记】2020-2021 Russia Team Open, High School Programming Contest (VKOSHP 20)

Pro

2020-2021 Russia Team Open, High School Programming Contest (VKOSHP 20)

Sol

B. Bacteria

其实只要保证对于第i轮分裂后的细菌,前i轮产生的细菌互不相同即可。

怎么保证呢?第i轮细菌的数量为 2 i 2^i 2i,长度则为 2 n − i 2^{n-i} 2ni,所以第i轮的01串共有 2 2 n − i 2^{2^{n-i}} 22ni种。

所以只需要找到一个最大的k,满足 2 k ≤ 2 2 n − i 2^k\leq 2^{2^{n-i}} 2k22ni,不等号前为细菌的数量,后为种类数,种类数小于等于数量即可保证。

那么此时的长度为 2 n − k 2^{n-k} 2nk,所以只需要构造出由0到 2 n − k − 1 2^{n-k}-1 2nk1的二进制串连起来即为答案。

D. Multiple Subject Lessons

正解是dp+数学,虽然搜索+数学打暴力,然后打表过了,但还是有一些值得思考的地方。

训练的时候连ploya都想到了,但是没想好……还是WA了几次,具体下面说。

其实就是把数字拆开,然后对于每一个数字出现的次数(假设为c)染k种颜色的方案数相乘,然后累加即为答案。

但是关键在于如何求“对于每一个数字出现的次数(假设为c)染k种颜色的方案数”呢?

开始想到了ploya,但是仔细想想还是会有问题的。这里虽然每个数字是等价的,但是不能看成ploya题目里的珠子(或者顶点)。

因为定理里面的珠子其实还是有一个连接顺序的(环),但是这里的所有数字是完全等价的。所以ploya错误。

正确答案其实是数学公式: C c + k − 1 k C_{c+k-1}^k Cc+k1k,为什么呢?考虑隔板法,但是前提是每个空隙都要有,所以给每个盒子都加一个球,一共k+c个球。

一共有k+c-1个位置,一共需要插入k个板子,所以答案为上式。

相关链接与图片:

https://zhidao.baidu.com/question/1927308947759504987.html

https://www.zhihu.com/question/314044456

https://www.cctry.com/thread-1439-1-1.html

J. Straight

感觉自己讲不明白,以及现在写的感觉以后也不一定能很快理解。

所以,直接贴我看明白的题解里面说的吧。

QQ截图20211026211316.png

Code

B. Bacteria

//By cls1277
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<sstream>
#include<set>
#include<cassert>
#include<bitset>
using namespace std;
typedef long long LL;
#define PI acos(-1)
#define INF 2147483647
#define eps 1e-7
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define lowbit(_) _&(-_)
#define mk(_,__) make_pair(_,__)
#define pii pair<int,int>
#define ls x<<1
#define rs x<<1|1
#define endl '\n'
inline LL read() {
	LL x = 0, f = 1;char c = getchar();
	while (!isdigit(c)) { if (c == '-')f = -f;c = getchar(); }
	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
	return x * f;
}

//const LL maxn = ;
int n,m,a[20],s;

int main() {
	ios::sync_with_stdio(false);
	#ifdef DEBUG
	freopen("data.txt","r",stdin);
	#endif
	cin>>n; m=n;
	while(m>(1<<(n-m))) m--;
	m=(1<<(n-m)); s=(1<<n);
	s/=m;
	//cout<<m<<endl;
	Fo(i,1,m) cout<<"0";
	Fo(i,1,s-1) {
		LL x=i,cnt=0; Ms(a,0);
		while(x) {
			a[++cnt]=x%2;
			x/=2;
		}
		Ro(j,m,1) cout<<a[j];
		//cout<<i<<" ";
	}
	return 0;
}

D. Multiple Subject Lessons

//By cls1277
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<sstream>
#include<set>
#include<cassert>
#include<bitset>
using namespace std;
typedef __int128 LL;
#define PI acos(-1)
#define INF 2147483647
#define eps 1e-7
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define lowbit(_) _&(-_)
#define mk(_,__) make_pair(_,__)
#define pii pair<LL,LL>
#define ls x<<1
#define rs x<<1|1
#define endl '\n'
inline LL read() {
	LL x = 0, f = 1;char c = getchar();
	while (!isdigit(c)) { if (c == '-')f = -f;c = getchar(); }
	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
	return x * f;
}

const LL maxn = 45;
unsigned long long n,k,anss;
LL d[maxn],f[maxn]; 

void init() {
	f[0]=1;
	Fo(i,1,35) f[i]=f[i-1]*i;
}

LL C(LL x,LL y) {
	return f[x]/f[y]/f[x-y];
}

//ploya wrong 
/*struct A {
	LL gcd(LL a, LL b) {
    	return b==0?a:gcd(b,a%b);  
	} 
	LL qpow(LL x , LL y) {
	    if(!y) return 1;
	    LL m = qpow(x,y>>1);
	    if(y&1) return m*m*x;
	    return m*m;
	}
	LL res(LL x, LL y) {
	    LL result = 0;  
	    for(LL i = 1; i <= y; i++)  
	        result += qpow(x,gcd(y,i));  
	    if(y%2)  
	        result += y*qpow(x,y/2+1);  
	    else  
	        result += (qpow(x,y/2)+qpow(x,y/2+1))*y/2;  
	    return result/y/2; 
	}
}a;*/

void dfs(LL x, LL y, LL z,LL s,LL d[]) {
	if(x==y) {
		if(s==n) {
			//Fo(i,1,y) cout<<d[i]<<" ";
			//cout<<endl;
			LL cnt[25]; Ms(cnt,0);
			bitset<25>vis;
			Fo(i,1,y) cnt[d[i]]++;
			LL aaa=1;
			Fo(i,1,y) {
				if(vis[d[i]]||!cnt[d[i]]) continue;
				vis[d[i]]=1;
				aaa=aaa*C(cnt[d[i]]+k-1,cnt[d[i]]);
			//	aaa=aaa*a.res(k,cnt[d[i]]);
			}
			anss+=aaa;
		}
		return ;
	}
	Fo(i,z,n) {
		d[x+1]=i;
		dfs(x+1,y,i,s+i,d);	
	}
	return ;
}

int main() {
	ios::sync_with_stdio(false);
	#ifdef DEBUG
	freopen("data.txt","r",stdin);
	freopen("sss.txt","w",stdout);
	#endif
	init();
	while(cin>>n>>k) {
		anss=0;
		Fo(i,1,n) {
			dfs(0,i,1,0,d);
		}
		//打表用的 
		cout<<"a["<<n<<"]["<<k<<"]="<<anss<<";"<<endl;
	//	cout<<anss<<endl;	
	}
	return 0;
}

J. Straight

//By cls1277
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<sstream>
#include<set>
#include<cassert>
#include<bitset>
using namespace std;
typedef long long LL;
#define PI acos(-1)
#define INF 2147483647
#define eps 1e-7
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define lowbit(_) _&(-_)
#define mk(_,__) make_pair(_,__)
#define pii pair<int,int>
#define ls x<<1
#define rs x<<1|1
#define endl '\n'
inline LL read() {
	LL x = 0, f = 1;char c = getchar();
	while (!isdigit(c)) { if (c == '-')f = -f;c = getchar(); }
	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
	return x * f;
}

const LL maxn = 1e5+5;
LL n,m,s,a[maxn],_m,ans; 

int main() {
	ios::sync_with_stdio(false);
	#ifdef DEBUG
	freopen("data.txt","r",stdin);
	#endif
	cin>>n>>m>>s;
	Fo(i,1,m) cin>>a[i];
	sort(a+1,a+m+1);
	_m=unique(a+1,a+m+1)-a-1;
	for(int i=1; i+m-s-1<=_m; i++) {
		LL ddbug = i+m-s-1;
		LL minn=max(a[i-1]+1,a[i+m-s-1]-m+1);
		LL maxx=min(a[i],n-m+1);
		if(minn>maxx) continue;
		ans+=maxx-minn+1;
	}
	cout<<ans;
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cls1277

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值