加载中…

返回上一页

CSP-S模拟20

下发文件页面

归隐

推式子.

可以发现每一次的大小都是上一次的三倍加一. 那么总共加和就是 3n - 3n-2 - 2 × 3n-3 - ... - (n - 1) × 30.

考虑后面这玩意怎么化.

发现它可以拆成 30 + (30 + 31) + (30 + 31 + 32) + ....

因为有一个结论(可以手推):30 + 31 + ... + 3n-1 = ,那么整个式子就化成了 .

记得把读入的数字减个 1,因为我没有考虑是 0 的情况.

然后,要用快速乘!因为这个炸了 long long 50 分没了!

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define mod 998244353
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar(); while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
ll n;
inline ll ksm(rll a,rll b) { rll ans=1; a%=mod; for(rll i=b;i;i>>=1) { if(i&1) ans=ans*a%mod; a=a*a%mod; } return ans; }
inline ll ksc(rll a,rll b) { rll ans=0; for(rll i=b;i;i>>=1) { if(i&1) ans=ans+a%mod; a=(a<<1)%mod; } return ans; }
int main()
{
	freopen("gy.in","r",stdin); freopen("gy.out","w",stdout);
	// for(rll i=1;i<=20;i++) 
	// {
	// 	rll ans=0;
	// 	for(rll j=0;j<=i-2;j++) ans+=pow(3,j)*(i-j-1); write(ans);put_;write(((pow(3,i)-1)/2-i)/2);putn;
	// }
	n=read()-1ll;write((ksm(3,n)-ksc((ksc((ksm(3,n)-1),ksm(2,mod-2))%mod-n+mod),ksm(2,mod-2))%mod+mod)%mod);
	return 0;
}

按位或

首先进行一个类似背包的预处理,设 dp[i][j] 表示 t子数中二进制下有 i奇数位(第 1、3、5… 位)和 j偶数位.

为什么要这么处理?因为还是一个结论:一个奇数位的数字模 3 后余 1,偶数位的数字模 3 后余 2.

那么转移仍然找子数:设 k < il < j,那么有 dp[i][j] += . 当然,只有在 3 | i + 2j 时才能转移.

然后就是计算答案了,仍然枚举 ij,设 cnt1 为奇数位个数、cnt2 为偶数位个数,那么有:

.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 64
#define mod 998244353
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar(); while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,t,cnt1,cnt2,sz,ans;
ll dp[maxn][maxn];
ll jc[maxn];
inline ll ksm(rll a,rll b) { rll ans=1; a%=mod; for(rll i=b;i;i>>=1) { if(i&1) ans=ans*a%mod; a=a*a%mod; } return ans; }
inline ll C(rll n,rll m) { return jc[n]*ksm(jc[m],mod-2)%mod*ksm(jc[n-m],mod-2)%mod; }
int main()
{
	freopen("or.in","r",stdin); freopen("or.out","w",stdout);
	jc[0]=1;for(rll i=1;i<maxn;i++) jc[i]=jc[i-1]*i%mod;
	n=read();t=read(); for(rll i=1;i<maxn;i++) if((t>>i-1)&1) i&1?cnt1++:cnt2++;
	for(rll i=0;i<=cnt1;i++) for(rll j=0;j<=cnt2;j++) for(rll k=0;k<=i;k++) for(rll l=0;l<=j;l++)
		if(!((k+(l<<1))%3)) (dp[i][j]+=C(i,k)*C(j,l)%mod)%=mod;
	for(rll i=0;i<=cnt1;i++) for(rll j=0;j<=cnt2;j++)
		(ans+=(((cnt1+cnt2-i-j&1?-1:1)*C(cnt1,i)*C(cnt2,j)%mod*ksm(dp[i][j],n)%mod)+mod)%mod)%=mod;
	write(ans);
	return 0;
}

最短路径

虚树. 放一个学长的博客,不想打了.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 2001
#define mod 998244353
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar(); while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,m,k;
ll jc[maxn],tg[maxn],dis[301][301],cnt,ans;
vector<ll> g[maxn],sel;
ll f[maxn],d[maxn],ds[maxn],sz[maxn],son[maxn],dfn[maxn],top[maxn],tot;
inline ll ksm(rll a,rll b) { rll ans=1; a%=mod; for(rll i=b;i;i>>=1) { if(i&1) ans=ans*a%mod; a=a*a%mod; } return ans; }
inline ll C(rll n,rll m) { return jc[n]*ksm(jc[m],mod-2)%mod*ksm(jc[n-m],mod-2)%mod; }
inline void dfs1(rll x,rll fa)
{
	f[x]=fa;d[x]=d[fa]+1;sz[x]=1;son[x]=0;
	for(rll i=0;i<g[x].size();i++)
	{
		rll to=g[x][i];if(to==fa) continue;
		dfs1(to,x);sz[x]+=sz[to];if(sz[to]>sz[son[x]]) son[x]=to;
		ds[x]+=ds[to];if((!ds[to])||ds[to]==m) continue;
		ans=(ans+(C(m,k)-C(ds[to],k)+mod-C(m-ds[to],k)+mod<<1)%mod)%mod;
	}
}
inline void dfs2(rll x,rll fa)
{
	dfn[x]=++tot;top[x]=fa;if(son[x]) dfs2(son[x],fa);
	for(rll i=0;i<g[x].size();i++) { rll to=g[x][i]; if(dfn[to]) continue; dfs2(to,to); }
}
inline ll lca(rll x,rll y)
{
	while(top[x]^top[y]) { if(d[top[x]]<d[top[y]]) swap(x,y);x=f[top[x]]; }
	if(d[x]<d[y]) return x; return y;
}
int main()
{
	freopen("tree.in","r",stdin); freopen("tree.out","w",stdout);
	jc[0]=1;for(rll i=1;i<maxn;i++) jc[i]=jc[i-1]*i%mod;
	n=read();m=read();k=read(); for(rll i=1;i<=m;i++) ds[tg[i]=read()]=1; sort(tg+1,tg+m+1);
	for(rll i=1,u,v;i<n;i++) g[u=read()].emplace_back(v=read()),g[v].emplace_back(u);
	dfs1(1,0);dfs2(1,1);
	for(rll i=1;i<=m;i++) for(rll j=i+1;j<=m;j++)
	{
		rll tot=0,x=tg[i],y=tg[j],dis=d[x]+d[y]-(d[lca(x,y)]<<1);
		for(rll k=1;k<=m;k++)
		{
			if(tg[k]==x||tg[k]==y) continue;
			if((d[x]+d[tg[k]]-(d[lca(x,tg[k])]<<1))>dis||(d[y]+d[tg[k]]-(d[lca(y,tg[k])]<<1))>dis) continue;
			if((d[x]+d[tg[k]]-(d[lca(x,tg[k])]<<1))==dis&&tg[k]<y) continue;
			if((d[y]+d[tg[k]]-(d[lca(y,tg[k])]<<1))==dis&&tg[k]<x) continue;
			tot++;
		}
		ans=(ans-dis*C(tot,k-2)%mod+mod)%mod;
	}
	write(ans*ksm(C(m,k),mod-2)%mod);
	return 0;
}

最短路

主席树维护高精,咕……(CF464E)

posted @ 2022-10-20 17:44  1Liu  阅读(8)  评论(0编辑  收藏  举报