暑假集训CSP提高模拟2
暑假集训CSP提高模拟2
唐完了哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
11/35...... 挂了
T1 活动投票
- 正解
摩尔投票板子,用投票方式对抗出次数大于一半的数
赛时想了个crt做法,结果质数选太小全挂了,乐
我们发现只有答案出现次数大于一半,我们的空间不够全部读入,尝试舍弃部分信息,对于任意数 数据删除 因为不会写crt挂分了
因为素数选小,常数巨大,全TLE,捆绑测试,遂挂
贴个代码先
#include<bits/stdc++.h>
#define llt long long
const llt N=101000;
using namespace std;
llt now,us[40][1054],n,l,ans[40],p[40],maxx[40],u,v,m;
vector<llt> prime;
llt exgcd(llt x,llt y,llt &a,llt &b)
{
if(x%y==0) {a=0,b=1;return y;}
llt gcd=exgcd(y,x%y,a,b),c=a;
a=b,b=c-a*(x/y);
return gcd;
}
void crt()
{
llt o;
for(int i=0;i<l-1;i++)
{
u=v=0;
o=exgcd(prime[i],prime[i+1],u,v);
u=(u%prime[i+1]+prime[i+1])%prime[i+1];
u=u*((ans[i+1]-ans[i])%prime[i+1]);
u=(u%prime[i+1]+prime[i+1])%prime[i+1];
m=u*prime[i]+ans[i];
ans[i+1]=m,prime[i+1]*=prime[i];
m%=prime[i+1];
}
printf("%lld\n",m);
}
int main()
{
#ifdef LOCAL
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
prime.push_back(1009);prime.push_back(1019);prime.push_back(1021);
l=prime.size();
prime.resize(100);
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&now);
for(int j=0;j<l;j++)
us[j][now%prime[j]]++;
}
for(int i=0;i<l;i++)
for(int j=0;j<prime[i];j++)
if(us[i][j]>maxx[i])
maxx[i]=us[i][j],ans[i]=j;
crt();
return 0;
}
T2 序列
感觉是一眼套路题,赛时想到的一个做法是扫描序列,对于一个数,如果是第一次出现,将权值加上
场上莫名其妙写挂掉了,挂掉
T3 Legacy
线段树优化建图板子,简单来说就是建棵线段树,通过中转点来减少连边数,注意出树和入树只有叶子联通
赛时不会,写了
T4 DP搬运工1
好题,难题。
这个好像叫预设型dp,我不会啊
首先发现枚举每一位复杂度是巨错无比的,这玩意因为优秀的阶乘复杂度荣获
我们发现可以dp,从小到大填数,你在填了这个数之后如果它的两端每有一个已经填过的数,当前数就会对那个
有一个显然的状压做法对吧,每一位填了就是
之后我们发现我们其实关心的只有每个
1 1 1 0 1 1 1 0
1 1 1 0 0 1 1 1
1 1 1 1 0 0 1 1
他们的贡献相同时,合法方案数都是一样的(因为在端点处的数个数相同),两边互不影响,所以我们将类似这种的情况都当作一个状态
所以状态设计就是 当前填到哪个数 分了几个段 最终贡献是多少
现在开始写转移,新加入的数有以下几种可能
- 加到某个区间端点,但不接上另一个区间,贡献是其权值
- 加到某个区间端点,同时接上另一个区间,贡献是其权值
倍 - 加到中间,不和任何区间相邻,没贡献
方程自然有了
大力dp之后输出
贴个代码:
#include<bits/stdc++.h>
#define llt long long
const llt mod=998244353;
using namespace std;
llt n,k,dp[60][60][2600],ans;
int main()
{
#ifdef LOCAL
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
scanf("%lld%lld",&n,&k);
dp[1][1][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int d=0;d<=k;d++)
{
if(d>=i) dp[i][j][d]+=dp[i-1][j][d-i]*2%mod*j%mod;
if(d>=2*i) dp[i][j][d]+=dp[i-1][j+1][d-2*i]*j%mod;
if(j>=1) dp[i][j][d]+=dp[i-1][j-1][d]*j%mod;
dp[i][j][d]%=mod;
}
}
}
for(int j=0;j<=k;j++)
ans+=dp[n][1][j],ans%=mod;
printf("%lld\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】