杭电多校2020第五场

Paperfolding

题意:

一张纸折叠K次,可以横着或竖着折叠,折叠后沿着十字剪开,询问剪开后剩余纸张的期望值。

题解:

横向折叠和纵向折叠对答案的影响是独立的,设横向折叠了x次,那么最后剪开完,会出现2x 条割线,即会有2x +1张纸,设纵向折叠了y次,同理,会有2y条割线,2y +1张纸,最后,纸张会被切割成 (2x + 1) * (2y +1)张,由于n = x + y,期望值可以表示为:
在这里插入图片描述
计算过程:
杭电多校2020第五场_第1张图片

根据二项式定理,最终可转换为:
杭电多校2020第五场_第2张图片
AC_CODE:

ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
void solve(){
	ll n;
	R(n);
	ll sum = powmod(2,n) + 1;
	ll k1 = powmod(3,n);
	ll k2 = powmod(2,n);
	ll k3 = powmod(k2,mod-2);
	ll k4 = k1 * k3 % mod;
	k4 = k4 * 2 % mod;
	sum = (sum + k4) % mod;
	W(sum);
}

Boring Game

题意:

将n张纸铺在一起,同方向折叠k次,给定一个序列,为纸张从上到下,正反两面赋值,问展开纸张后,纸张从上到下,从左到右的值是多少?

题解:

每次折叠的过程,都是将原序列上半部分翻转并合并到下半部分的左侧,模拟即可。

杭电多校2020第五场_第3张图片

AC_CODE:


void solve(){
	int n,k;
	R(n,k);
	int p = 2 * n * powmod(2,k);
	VI v;
	FOR(i,1,p) {
		int u;
		R(u);
		v.PB(u);
	}
	int mid = p >> 1;
	int u = 1;
	REPP(i,0,k) {
		VI t;
		VI q;
		int num = 0;
		int m = p >> 1;
		for(auto x: v) {
			num += 1;
			if(num > m) break;
			q.PB(x);
		}
		for(int ii=0,jj=m-1; ii<m; ++ii,--jj) {
			v[jj] = q[ii];
		}
		for(int ii=0; ii<mid; ++ii) {
			for(int j=ii*u; j<(ii+1)*u; ++j) {
				t.PB(v[j]);
			}
			for(int j=(p>>1)+ii*u; j<(ii+1)*u+(p>>1); ++j) {
				t.PB(v[j]);
			}
		}
		v = t;
		u <<= 1;
		mid >>= 1;
	}
	W(v);
}

你可能感兴趣的:(杭电多校2020第五场)