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 < i 且 l < j,那么有 dp[i][j] += . 当然,只有在 3 | i + 2j 时才能转移.
然后就是计算答案了,仍然枚举 i 和 j,设 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)
--END--
我的博客: 𝟷𝙻𝚒𝚞
本文链接: https://www.cnblogs.com/1Liu/p/16810739.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!