杭电多校2020第五场

Paperfolding

题意:

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

题解:

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

根据二项式定理,最终可转换为:
在这里插入图片描述
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次,给定一个序列,为纸张从上到下,正反两面赋值,问展开纸张后,纸张从上到下,从左到右的值是多少?

题解:

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

在这里插入图片描述

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);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值