zr2019暑期高端峰会AB组day7

zr2019暑期高端峰会AB组day7

dls的比赛好duliu啊

A. 松

link

  • 搜索加优化,长度小于等于16的打表预处理
  • 做一个位序逆置换,就变得跟蝴蝶操作一样,每次我们用两个压位的二进制数做一次位运算即可

B. 集合

link

  • 赛场上很快就会了一个 n 3 n^3 n3的做法,枚举最大差,枚举最小差,枚举取多少个数,利用差分后的数组,等于求不定方程解的个数,60分,后来才知道这个做法应该是80分的,枚举取多少个数是有限制的,复杂度 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n),好的,不好好算复杂度就挂了20分
  • 枚举最小差i,选了j个数,复杂度O(nlogn),现在考虑如何O(1)算出知最小差和数的个数的贡献,即 ∑ i ∗ 最 大 差 ∗ 方 案 数 = ∑ i ∗ ( m x − m n ) ∗ 方 案 数 = i ∗ ( ∑ m x ∗ 方 案 数 − ∑ m n ∗ 方 案 数 ) \sum i*最大差*方案数=\sum i*(mx-mn)*方案数=i*(\sum mx*方案数-\sum mn*方案数) i=i(mxmn)=i(mxmn)
  • 接下来推式子算 ∑ m n ∗ 方 案 数 \sum mn*方案数 mn,枚举最小值 c c c

∑ c = 1 n − ( i − 1 ) ( j − 1 ) ( n − ( i − 1 ) ( j − 1 ) − c j − 1 ) ∗ c \sum_{c=1}^{n-(i-1)(j-1)} \tbinom{n-(i-1)(j-1)-c}{j-1} *c c=1n(i1)(j1)(j1n(i1)(j1)c)c

  • 经过一波化简最小值贡献等于 ( n − ( i − 1 ) ( j − 1 ) + 1 j ) \tbinom{n-(i-1)(j-1)+1}{j} (jn(i1)(j1)+1)
  • 最大值可以和最小值一一对应,对称着来等于 ( n + 1 ) ∗ 方 案 数 − 最 小 值 贡 献 (n+1)*方案数-最小值贡献 (n+1)
  • ( n + 1 ) ( n − ( i − 1 ) ( j − 1 ) j ) − 2 ( n − ( i − 1 ) ( j − 1 ) + 1 j + 1 ) (n+1)\tbinom{n-(i-1)(j-1)}{j}-2\tbinom{n-(i-1)(j-1)+1}{j+1} (n+1)(jn(i1)(j1))2(j+1n(i1)(j1)+1)

C. 最短路

link

  • dls:到了今天最简单的题
  • 这题发现通过的桥并不是很多,可以把关键桥建出来跑最短路,也可以直接贪心地,向内向外跳
  • 感觉好麻烦的样子,不写了不写了
T2赛场代码
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register ll i=(a);i<=(b);i++)
#define For(i,a,b) for (register ll i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
using namespace std;
typedef long long ll;
const int N=5050;
ll n,mod,pre[N],inv[N],ans=0;
inline ll read()
{
	int x=0,f=1;
	char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return f*x;
}
inline ll qpow(ll a,ll b)
{
	ll ret=1;
	while (b)
	{
		if (b&1) ret=ret*a%mod;
		b>>=1;
		a=a*a%mod;
	}
	return ret;
}
inline void init()
{
	pre[0]=1;
	FOR(i,1,n) pre[i]=pre[i-1]*i%mod;
	inv[n]=qpow(pre[n],mod-2);
	For(i,n-1,0) inv[i]=inv[i+1]*(i+1)%mod;
	return;
}
inline ll C(ll a,ll b)
{
	if (b<0||a<0) return 0;
	if (a<b) return 0;
	ll ret=pre[a]*inv[b]%mod*inv[a-b]%mod;
	return ret;
}
int main()
{
	n=read(),mod=read();
	init();
	FOR(mx,1,n-1)
	{
		FOR(mn,1,mx)
		{
			ll tmp=0;
			FOR(k,1,n)
			{
				tmp=(tmp+C(mx-k*(mn-1)-1,k-1)-C(mx-k*(mn-1)-k-1,k-1)+mod)%mod;
			}
			ans=(ans+tmp*(n-mx)%mod*mx%mod*mn%mod)%mod;
		}
	}
	printf("%lld\n",ans);
	return 0;
}
T2赛后代码
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register ll i=(a);i<=(b);i++)
#define For(i,a,b) for (register ll i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll n,mod,pre[N],inv[N],ans=0,tmp1=0,tmp2=0;
inline ll read()
{
	int x=0,f=1;
	char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return f*x;
}
inline ll qpow(ll a,ll b)
{
	ll ret=1;
	while (b)
	{
		if (b&1) ret=ret*a%mod;
		b>>=1;
		a=a*a%mod;
	}
	return ret;
}
inline void init()
{
	pre[0]=1;
	FOR(i,1,n+1) pre[i]=pre[i-1]*i%mod;
	inv[n+1]=qpow(pre[n+1],mod-2);
	For(i,n,0) inv[i]=inv[i+1]*(i+1)%mod;
	return;
}
inline ll C(ll a,ll b)
{
	if (b<0||a<0) return 0;
	if (a<b) return 0;
	ll ret=pre[a]*inv[b]%mod*inv[a-b]%mod;
	return ret;
}
int main()
{
	n=read(),mod=read();
	init();
	for (register int i=1;i<n;i++)
		for (register int j=2;i*(j-1)<n;j++)
			ans=(ans+(n+1)*C(n-(i-1)*(j-1),j)%mod-2*C(n-(i-1)*(j-1)+1,j+1)%mod+mod)%mod; 

	printf("%lld\n",ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值