将我隐藏,成为星空中崭新的孤岛|

cc0000

园龄:5年粉丝:14关注:5

ABC351 简要题解

A,B,C都是语法题跳了。

D

让你构造 300 个数,输入 n,使得这 300 个数选不超过 3 个加起来可以表示出 1n 所有的数

一开始想二进制拆分,然后发现总会超。

然后神说可以十进制,恍然大明白。就是 n 最大 106,然后分成 3 组,每组 99 个数,正好能装下。就是第一组是 199,第二组是 1009900,第三组是 10000990000,正好所有数都能表示出来,297 个数。

E

DP简单题。就是设 fi,0/1 到第 i 种操作,这种选不选的最小代价,然后对于第一种操作选不选分别讨论一下就行。

F

分别是 dfs 树和 bfs 树。

对于第一种,如果存在横叉边,那一定会在 dfs 的过程中先走那条边,导致不存在横叉边,只有树边和返祖边。

对于第二种,如果存在返祖边,那么它正常应该在它祖先被扩展时一起扩展进去,所以一定不存在返祖边。

G

计算几何——半平面交

跳了

Ex

假设一开始的 n 个数是 a1an。然后提起一层时的 n1 个数为 a1+a2,a2+a3,再往上提一层为 a1+2a2+a3,a2+2a3+a4,再下一层为 a1+3a2+3a3+a4,a2+3a3+3a4+a5

然后发现全是二项式系数。

也就是到第 i 层时,第 j 个数为 k=0niCnikaj+k

这样复杂度还是会寄。观察到 m 比较小,所以考虑从这里下手。

因为一个数会覆盖一段,一段里又可以分成 m 段,每段里的 a 都相同,只有二项式系数不同。所以如果能快速地求二项式系数的前缀和,问题就解决了。

对于组合数的前缀和:i=0kCni,考虑先用卢卡斯定理,推个式子,然后用类似整除分块的东西拆一下,然后就能递归算了。左转这道题(懒得打式子了)[SHOI2015]超能粒子炮·改

但是你发现,对于 k 个数,m 段都求,再算个前缀和是 O(kmlog2n) 的,过不了。

但是发现,每次移动一位, m 段的贡献只有每段的分界点会有变化。其他的和上一次是一样的。 所以每次只需要维护 O(m) 个变化量,所以优化成了 O(kmlogn) 的。

但是还是不行,还是需要优化。

我们发现复杂度卡在求组合数上。我们考虑这东西能不能被优化掉。我们发现 Lucas 的过程就是相当于 mod 进制的拆分。所以我们考虑把进制里高位和低位分别预处理出来,然后到时直接查表就行。

具体来讲就是 Cnmn 是固定的,所以把 Cn%76i 的所有的结果全预处理出来,Cn/76i 也全预处理出来。然后如果查 Cnm 就直接查 Cn/76m/76×Cn%76m%76.

这样我们就把它优化成了 O(km)

注意卡常

我好像写麻烦了,但是神的代码好什么看不懂。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll c[20][20],f[20][20];
ll n;int m,K;
int mod=7;
int a[203],cc[203];int posl[203],posr[203],Lx[203],Rx[203];
ll Lucas(ll n,ll K)
{
	if(!K) return 1;
	if(n<K) return 0; 
	if(n==K) return 1; 
	return (c[n%mod][K%mod]*Lucas(n/mod,K/mod))%mod;
}
ll f1[200030],f2[200030];
ll lucas(ll n,ll k)
{
	return (f1[k%117649]*f2[k/117649])%mod;
}
ll F(ll n,ll K)
{
	if(K<0) return 0;
	if(!K||!n) return 1;
	if(n<mod&&K<mod) return f[n][K];
	return ((f[n%mod][mod-1]*F(n/mod,K/mod-1))%mod+(f[n%mod][K%mod]*Lucas(n/mod,K/mod))%mod)%mod;
}
int main()
{
//	freopen("p.in","r",stdin);
//	freopen("p.out","w",stdout);
	c[0][0]=1;
	for(int i=1;i<=7;i++)
	{
		c[i][0]=1; 
		for(int j=1;j<=i;j++)
			c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
	}
	for(int i=0;i<=7;i++)
	{
		f[i][0]=1;
		for(int j=1;j<=7;j++)
			f[i][j]=(f[i][j-1]+c[i][j])%mod;
	}
	scanf("%lld%d%d",&n,&m,&K);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a[i],&cc[i]);	
	}
	if(n==K) 
	{
		for(int i=1;i<=m;i++)
		{
			while(cc[i]--)
				printf("%d ",a[i]);
		}
		return 0;
	}
	ll B1=0;ll lst=0; ll kk=0;
	memset(posl,-1,sizeof(posl)); memset(posr,-1,sizeof(posr));
	for(int i=1;i<=m;i++)
	{
		Lx[i]=kk,Rx[i]=kk+cc[i]-1;
		if(kk>n-K+1) {kk=cc[i]+kk;continue;}
		ll cur=F(n-K,min(kk+cc[i]-1,n-K));
		B1=(B1+(cur-lst)*a[i])%mod; B1=(B1+mod)%mod;
		posr[i]=min(kk+cc[i]-1,n-K); posl[i]=kk;
		kk=kk+cc[i]; lst=cur;
	}
	int mx=117649;
	for(int i=0;i<=mx;i++) f1[i]=Lucas((n-K)%mx,i);
	for(int i=0;i<=mx;i++) f2[i]=Lucas((n-K)/mx,i);
	int st=1;
	printf("%lld ",B1);
//		for(int i=1;i<=m;i++) fprintf(stderr,"posl[%d]=%d,posr[%d]=%d\n",i,posl[i],i,posr[i]);
	int LL=0,RR=n-K;
	for(int j=2;j<=K;j++)
	{
		ll ret=B1;
		LL++; RR++;
		for(int i=st;i<=m;i++)
		{
			int lx=posl[i],rx=posr[i];
			if(lx==0) 
			{
				if(rx==0){ret-=a[i]; posl[i]=posr[i]=-2;st=i+1;continue;} 
				else if(rx==n-K&&Rx[i]>=RR) break;
				else if(rx==n-K&&Rx[i]==RR-1) {ret-=(f1[rx%117649]*f2[rx/117649])*a[i],posr[i]=rx-1;ret=(ret+mod)%mod;continue;}
				else {ret-=(f1[rx%117649]*f2[rx/117649])*a[i],posr[i]=rx-1;ret=(ret+mod)%mod;continue;}
			}
			else if(lx>0)
			{
				if(rx>0&&(rx!=n-K||(rx-lx+1==cc[i]))) 
				{
					lx--;ret=(ret+f1[lx%117649]*f2[lx/117649]*a[i])%mod; posl[i]=lx;
					ret-=f1[rx%117649]*f2[rx/117649]*a[i],ret=(ret+mod)%mod, posr[i]=rx-1;
				}
				else 
					posl[i]=lx-1,ret=(ret+f1[posl[i]%117649]*f2[posl[i]/117649]*a[i])%mod;
			}
			else if(lx==-2) continue;
			else if(lx==-1)
			{
				if(posr[i-1]==n-K-1) ret=(ret+a[i])%mod,posl[i]=posr[i]=n-K;
				break; 
			}
		}
		printf("%lld ",(ret+7)%7);
		//fprintf(stderr,"%d %.3lf\n",j,1.0*clock()/CLOCKS_PER_SEC);
	//	for(int i=1;i<=m;i++) fprintf(stderr,"posl[%d]=%d,posr[%d]=%d\n",i,posl[i],i,posr[i]);
		B1=ret;
	}

}

本文作者:cc0000

本文链接:https://www.cnblogs.com/cc0000/p/16945775.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   cc0000  阅读(168)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起