CSP2024 前集训:多校A层冲刺NOIP2024模拟赛05
前言
一次模拟赛四个计数,后三道一个 trick,yl 他妈都能被气活:
T2、T3、T4 全是正难则反的 trick,T3、T4 都需要回退背包,T1 也可以背包。
T2 没想到正难则反一直死磕心态炸了,其实要试看看 T3 搞不好还想出来了。
以后再想不到正难则反记得抽死我谢谢。
T1 好数
可以直接暴力背包套 bitset 操过去,复杂度
也可以移项
点击查看代码
#include<bits/stdc++.h> #define ll long long #define endl '\n' #define sort stable_sort using namespace std; const int N=5010,M=6e5+10,V=1e5; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=true; register char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') z=0; for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);} template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar((x%10)+'0');} template<typename Tp> inline void write(Tp x){if(x<0)putchar('-'),x=~x+1;wt(x);} template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);} int n,ans,a[N]; bitset<M>f[5]; signed main() { freopen("number.in","r",stdin),freopen("number.out","w",stdout); read(n); for(int i=1;i<=n;i++) read(a[i]),a[i]+=V; f[0][0]=1; for(int i=1;i<=n;i++) { ans+=f[3][a[i]+2*V]; for(int j=1;j<=3;j++) f[j]|=(f[j-1]<<a[i]); } write(ans); }
T2 SOS字符串
正难则反,SOS
个数
赛时一直正着推,没想到就算 SOS
数量固定也会有算重的,遂
所以以后先把暴力打出来方便拍,还有组合数搞不出来的时候想一想 DP。
点击查看代码
#include<bits/stdc++.h> #define ll long long #define endl '\n' #define sort stable_sort using namespace std; const int N=1e6+10,P=1e9+7; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=true; register char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') z=0; for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);} template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar((x%10)+'0');} template<typename Tp> inline void write(Tp x){if(x<0)putchar('-'),x=~x+1;wt(x);} template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);} int n,ans=1,f[2][3][3]; signed main() { freopen("sos.in","r",stdin),freopen("sos.out","w",stdout); read(n); f[0][0][0]=1; for(int i=1,x=1,y=0;i<=n;i++,x^=1,y^=1,ans=26ll*ans%P) for(int j=0;j<=2;j++) { f[x][j][0]=25ll*(f[y][j][0]+f[y][j][2])%P; (f[x][j][0]+=24ll*f[y][j][1]%P)%=P; if(j) (f[x][j][0]+=f[y][j-1][2])%=P; f[x][j][1]=(f[y][j][0]+f[y][j][1])%P; f[x][j][2]=f[y][j][1]; } for(int i=0,x=n&1;i<=2;i++) for(int j=0;j<=2;j++) (ans+=P-f[x][i][j])%=P; write(ans); }
T3 集训营的气球
一样的 trick 正难则反,然后就是回退背包板子。
点击查看代码
#include<bits/stdc++.h> #define ll long long #define endl '\n' #define sort stable_sort using namespace std; const int N=1e6+10,M=20,P=1e9+7; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=true; register char c=getchar_unlocked(); for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0; for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);} template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');} template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);} template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);} int n,c,m,a[N],b[N]; ll ans=1,f[M]; int inv(ll a,int b=P-2) {ll res=1; for(;b;(a*=a)%=P,b>>=1) if(b&1) (res*=a)%=P; return res;} signed main() { freopen("balloon.in","r",stdin),freopen("balloon.out","w",stdout); read(n,c); f[0]=1; for(int i=1;i<=n;i++) read(a[i]); for(int i=1;i<=n;i++) read(b[i]); for(int i=1;i<=n;(f[0]=f[0]*b[i]%P)%=P,(ans*=a[i]+b[i])%=P,i++) for(int j=c-1;j>=1;j--) f[j]=(f[j-1]*a[i]%P+f[j]*b[i]%P)%P; read(m); for(int i=1,o,x,y,sum,va,vb;i<=m;i++) { read(o,x,y); va=inv(a[o]),vb=inv(b[o]),sum=0; (ans*=1ll*inv(a[o]+b[o])*(x+y)%P)%=P,(f[0]*=vb)%=P; for(int j=1;j<c;j++) f[j]=(f[j]-f[j-1]*a[o]%P+P)*vb%P; for(int j=c-1;j>=1;j--) (sum+=(f[j]=(f[j-1]*x%P+f[j]*y%P)%P))%=P; a[o]=x,b[o]=y; write((ans-sum-((f[0]*=y)%=P)+(P<<1))%P),puts(""); } }
T4 连通子树与树的重心
先求出原树的重心,可能有一个或两个,分类讨论。
两个重心
这个比较容易处理,设两个重心分别为
设
最后答案为
-
关于本题树形背包的复杂度:
转移等价于找出一组
给 做出贡献,遂每组 只可能被记到一次,遂复杂度为 。
一个重心
先以重心为根跑一遍上面的 DP,然后考虑容斥,依然是正难则反。
求出
点击查看代码
#include<bits/stdc++.h> #define ll long long #define endl '\n' #define sort stable_sort #define pb push_back using namespace std; const int N=5010,P=10007; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=true; register char c=getchar_unlocked(); for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0; for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);} template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');} template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);} template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);} int n,ans,rt[3],sz[N],mx[N],f[N][N],g[N][N]; vector<int>e[N]; void getrt(int x,int t) { sz[x]=1; for(int y:e[x]) if(y!=t) getrt(y,x),sz[x]+=sz[y],mx[x]=max(mx[x],sz[y]); mx[x]=max(mx[x],n-sz[x]); if(mx[x]<=(n>>1)) rt[++rt[0]]=x; } void dfs(int x,int t) { sz[x]=1,f[x][0]=f[x][1]=1; for(int y:e[x]) if(y!=t) { dfs(y,x),sz[x]+=sz[y]; for(int i=sz[x];i;i--) for(int j=1;j<=min(sz[y],i-1);j++) (f[x][i]+=f[x][i-j]*f[y][j]%P)%=P; } } signed main() { freopen("tree.in","r",stdin),freopen("tree.out","w",stdout); read(n); for(int i=1,x,y;i<n;i++) read(x,y),e[x].pb(y),e[y].pb(x); getrt(1,0); if(!(rt[0]&1)) { cerr<<1<<endl; dfs(rt[1],rt[2]),dfs(rt[2],rt[1]); for(int i=1;i<=n;i++) (ans+=f[rt[1]][i]*f[rt[2]][i]%P)%=P; return write(ans),puts(""),0; } int x=rt[1]; dfs(x,0); for(int i=1;i<=n;i++) (ans+=f[x][i])%=P; for(int y:e[x]) for(int i=1;i<=n;i++) { g[y][i]=f[x][i]; for(int j=1;j<=min(i,sz[y]);j++) (g[y][i]+=P-g[y][i-j]*f[y][j]%P)%=P; } for(int y:e[x]) for(int i=1;i<=n;i++) for(int j=(i+1)/2;j<=min(i,sz[y]);j++) (ans+=P-f[y][j]*g[y][i-j]%P)%=P; write(ans),puts(""); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具