2025省选模拟5
2025省选模拟5
题目来源: 2024省选联测11
HZTG5843. Giao 徽的烤鸭
-
部分分
:爆搜。 :分讨菊花的三种情况。
点击查看代码
struct node { int nxt,to; }e[10010]; int head[5010],a[5010],b[5010],dis[5010][5010],vis[5010],cnt=0,ans=0; vector<int>col[510][510]; void add(int u,int v) { cnt++; e[cnt].nxt=head[u]; e[cnt].to=v; head[u]=cnt; } void get_dis(int x,int fa,int rt) { col[rt][dis[rt][x]].push_back(x); for(int i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=fa) { dis[rt][e[i].to]=dis[rt][x]+1; get_dis(e[i].to,x,rt); } } } int get_p(int x,int n) { for(int i=0;i<=n;i++) { for(int j=0;j<col[x][i].size();j++) { if(vis[col[x][i][j]]==0) return i-1; } } return n-1; } void dfs(int pos,int n,int sum) { if(pos==n+1) { for(int i=1;i<=n;i++) { if(vis[i]==1) { sum+=b[get_p(i,n)]; } } ans=max(ans,sum); return; } vis[pos]=1; dfs(pos+1,n,sum-a[pos]); vis[pos]=0; dfs(pos+1,n,sum); } int main() { #define Isaac #ifdef Isaac freopen("duck.in","r",stdin); freopen("duck.out","w",stdout); #endif int n,u,v,flag=1,sum=0,i; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=0;i<=n-1;i++) cin>>b[i]; for(i=1;i<=n-1;i++) { cin>>u>>v; add(u,v); add(v,u); flag&=(u==i+1&&v==1); } if(flag==1) { for(i=2;i<=n;i++) sum+=max(b[0]-a[i],0); ans=max(ans,sum); sum=-a[1]; for(i=2;i<=n;i++) sum+=max(b[1]-a[i],0); ans=max(ans,b[0]+sum); sum=-a[1]; for(i=2;i<=n;i++) sum+=b[n-1]-a[i]; ans=max(ans,b[n-1]+sum); } else { for(i=1;i<=n;i++) get_dis(i,0,i); dfs(1,n,0); } cout<<ans<<endl; return 0; }
-
正解
- 设
表示以 为根的子树内离 距离 的点都办会员卡的最大利润。 - 转移时为保证
正确地加入决策集合需保证 ,化简得到 。 - 为方便不办会员卡时的转移,整体将下标右移一位,令
表示 不办会员卡的最大利润。
点击查看代码
struct node { ll nxt,to; }e[10010]; ll head[5010],a[5010],b[5010],f[5010][5010],cnt=0,n; void add(ll u,ll v) { cnt++; e[cnt].nxt=head[u]; e[cnt].to=v; head[u]=cnt; } void dfs(ll x,ll fa) { for(ll i=1;i<=n;i++) f[x][i]=b[i-1]-a[x]; f[x][n+1]=-0x3f3f3f3f3f3f3f3f; for(ll i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=fa) { dfs(e[i].to,x); f[x][0]+=max(f[e[i].to][0],f[e[i].to][1]); for(ll j=1;j<=n;j++) { f[x][j]+=max({f[e[i].to][j-1],f[e[i].to][j],f[e[i].to][j+1]}); } } } } int main() { #define Isaac #ifdef Isaac freopen("duck.in","r",stdin); freopen("duck.out","w",stdout); #endif ll u,v,ans=0,i; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=0;i<=n-1;i++) cin>>b[i]; for(i=1;i<=n-1;i++) { cin>>u>>v; add(u,v); add(v,u); } dfs(1,0); for(i=0;i<=n;i++) ans=max(ans,f[1][i]); cout<<ans<<endl; return 0; }
- 设
HZTG5844. A Dance of Fire and Ice
- 原题: Gym103428C Assign or Multiply
- 观察到每次赋值相互独立,只需要处理乘法的情况。
- 部分分
-
:背包 转移。点击查看代码
ll pd[1000010],a[1000010],op,p; bitset<200010>ans,f[2]; void add(ll x) { op^=1; f[op]=f[op^1]; for(ll i=f[op^1]._Find_first();i<=p;i=f[op^1]._Find_next(i)) f[op][i*x%p]=1; } void mul(ll x) { for(ll i=f[op]._Find_first();i<=p;i=f[op]._Find_next(i)) ans[i*x%p]=1; } int main() { #define Isaac #ifdef Isaac freopen("dance.in","r",stdin); freopen("dance.out","w",stdout); #endif ll n,i; scanf("%lld%lld",&p,&n); a[0]=f[op][1]=1; for(i=1;i<=n;i++) { scanf("%lld%lld",&pd[i],&a[i]); if(pd[i]==1) add(a[i]); } for(i=0;i<=n;i++) { if(pd[i]==0) mul(a[i]); } printf("%lld\n",ans.count()); return 0; }
-
:使用巴雷特约减优化上述取模过程。点击查看代码
#include "MATH/Barrett.h"// oldyan 的 CP-template-main #endif int pd[1000010],a[1000010],op,p; bitset<200010>ans,f[2]; int main() { #define Isaac #ifdef Isaac freopen("dance.in","r",stdin); freopen("dance.out","w",stdout); #endif int n,i,j; scanf("%d%d",&p,&n); OY::Barrett32 brt(p); a[0]=f[op][1]=1; for(i=1;i<=n;i++) { scanf("%d%d",&pd[i],&a[i]); if(pd[i]==1) { op^=1; f[op]=f[op^1]; for(j=f[op^1]._Find_first();j<=p;j=f[op^1]._Find_next(j)) { f[op][brt.multiply(j,a[i])]=1; } } } for(i=0;i<=n;i++) { if(pd[i]==0) { for(j=f[op]._Find_first();j<=p;j=f[op]._Find_next(j)) { ans[brt.multiply(j,a[i])]=1; } } } printf("%d\n",ans.count()); return 0; }
-
- 正解
-
考虑通过原根及模意义下的对数将乘法转化为加法,然后在对数
意义下进行背包 转移。 -
使用
bitset
加速,中途若转移后的状态与原状态相等则退出转移以此进行剪枝。点击查看代码
ll lg[200010],cnt[200010]; vector<ll>result; bitset<200010>f,g; void divide(ll n) { result.clear(); for(ll i=2;i*i<=n;i++) { if(n%i==0) { result.push_back(i); while(n%i==0) n/=i; } } if(n>1) result.push_back(n); } ll qpow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) ans=ans*a%p; b>>=1; a=a*a%p; } return ans; } bool check(ll x,ll p,ll phi) { if(qpow(x,phi,p)!=1) return false; for(ll i=0;i<result.size();i++) { if(qpow(x,phi/result[i],p)==1) return false; } return true; } ll min_pr(ll p,ll phi) { for(ll i=1;i<=p-1;i++) { if(check(i,p,phi)==true) return i; } return -1; } int main() { #define Isaac #ifdef Isaac freopen("dance.in","r",stdin); freopen("dance.out","w",stdout); #endif ll p,phi,n,pr,pd,x,ans=0,i,j; scanf("%lld%lld",&p,&n); phi=p-1; divide(phi); pr=min_pr(p,phi); for(i=0,x=1;i<=phi-1;i++,x=x*pr%p) lg[x]=i; for(i=1;i<=n;i++) { scanf("%lld%lld",&pd,&x); ans|=(x==0); if(pd==0) f[lg[x]]=1; else cnt[lg[x]]++; } f[0]=1; for(i=0;i<=phi-1;i++) { for(j=1;j<=cnt[i];j++) { g=f|(f<<i)|(f>>(phi-i)); if(f==g) break; f=g; } } for(i=0;i<=phi-1;i++) ans+=f[i]; printf("%lld\n",ans); return 0; }
-
Gym103428C Assign or Multiply 上要求恰好
次操作,只需要记录一下 并在最后计入答案,需要加火车头优化。点击查看代码
#pragma GCC optimize(3) #pragma GCC target("avx") #pragma GCC optimize("Ofast") #pragma GCC optimize("inline") #pragma GCC optimize("-fgcse") #pragma GCC optimize("-fgcse-lm") #pragma GCC optimize("-fipa-sra") #pragma GCC optimize("-ftree-pre") #pragma GCC optimize("-ftree-vrp") #pragma GCC optimize("-fpeephole2") #pragma GCC optimize("-ffast-math") #pragma GCC optimize("-fsched-spec") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("-falign-jumps") #pragma GCC optimize("-falign-loops") #pragma GCC optimize("-falign-labels") #pragma GCC optimize("-fdevirtualize") #pragma GCC optimize("-fcaller-saves") #pragma GCC optimize("-fcrossjumping") #pragma GCC optimize("-fthread-jumps") #pragma GCC optimize("-funroll-loops") #pragma GCC optimize("-fwhole-program") #pragma GCC optimize("-freorder-blocks") #pragma GCC optimize("-fschedule-insns") #pragma GCC optimize("inline-functions") #pragma GCC optimize("-ftree-tail-merge") #pragma GCC optimize("-fschedule-insns2") #pragma GCC optimize("-fstrict-aliasing") #pragma GCC optimize("-fstrict-overflow") #pragma GCC optimize("-falign-functions") #pragma GCC optimize("-fcse-skip-blocks") #pragma GCC optimize("-fcse-follow-jumps") #pragma GCC optimize("-fsched-interblock") #pragma GCC optimize("-fpartial-inlining") #pragma GCC optimize("no-stack-protector") #pragma GCC optimize("-freorder-functions") #pragma GCC optimize("-findirect-inlining") #pragma GCC optimize("-fhoist-adjacent-loads") #pragma GCC optimize("-frerun-cse-after-loop") #pragma GCC optimize("inline-small-functions") #pragma GCC optimize("-finline-small-functions") #pragma GCC optimize("-ftree-switch-conversion") #pragma GCC optimize("-foptimize-sibling-calls") #pragma GCC optimize("-fexpensive-optimizations") #pragma GCC optimize("-funsafe-loop-optimizations") #pragma GCC optimize("inline-functions-called-once") #pragma GCC optimize("-fdelete-null-pointer-checks") ll lg[200010],cnt[200010]; vector<ll>result; bitset<200010>f,g; void divide(ll n) { result.clear(); for(ll i=2;i*i<=n;i++) { if(n%i==0) { result.push_back(i); while(n%i==0) n/=i; } } if(n>1) result.push_back(n); } ll qpow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) ans=ans*a%p; b>>=1; a=a*a%p; } return ans; } bool check(ll x,ll p,ll phi) { if(qpow(x,phi,p)!=1) return false; for(ll i=0;i<result.size();i++) { if(qpow(x,phi/result[i],p)==1) return false; } return true; } ll min_pr(ll p,ll phi) { for(ll i=1;i<=p-1;i++) { if(check(i,p,phi)==true) return i; } return -1; } int main() { // #define Isaac #ifdef Isaac freopen("dance.in","r",stdin); freopen("dance.out","w",stdout); #endif ll p,phi,n,pr,pd,x,tmp=1,ans=0,i,j; scanf("%lld%lld",&p,&n); phi=p-1; divide(phi); pr=min_pr(p,phi); for(i=0,x=1;i<=phi-1;i++,x=x*pr%p) lg[x]=i; for(i=1;i<=n;i++) { scanf("%lld%lld",&pd,&x); ans|=(x==0); if(pd==0) f[lg[x]]=1; else { tmp=tmp*x%p; cnt[lg[x]]++; } } for(i=0;i<=phi-1;i++) { for(j=1;j<=cnt[i];j++) { g=f|(f<<i)|(f>>(phi-i)); if(f==g) break; f=g; } } if(tmp!=0) f[lg[tmp]]=1; for(i=0;i<=phi-1;i++) ans+=f[i]; printf("%lld\n",p-ans); return 0; }
-
挂一下题解的做法。
-
HZTG5845. 挖掘机技术哪家强
-
部分分
:建图后 Bron Kerbosch 求解最大团。
点击查看代码
int p[200010],R[80][200010],P[80][200010],ans=0; map<pair<int,int>,int> e; bool find(int u,int v) { return e.find(make_pair(u,v))!=e.end(); } void Bron_Kerbosch(int dep,int r,int p) { if(p==0||dep>75) { ans=max(ans,r); return; } int u=P[dep][1]; for(int i=1;i<=p;i++) { if(find(u,P[dep][i])==false) { for(int j=1;j<=r;j++) R[dep+1][j]=R[dep][j]; R[dep+1][r+1]=P[dep][i]; int np=0; for(int j=1;j<=p;j++) { if(find(P[dep][i],P[dep][j])==true) { np++; P[dep+1][np]=P[dep][j]; } } Bron_Kerbosch(dep+1,r+1,np); P[dep][i]=0; } } } int main() { #define Isaac #ifdef Isaac freopen("excavator.in","r",stdin); freopen("excavator.out","w",stdout); #endif int n,m,x,i; cin>>n>>m; for(i=1;i<=n;i++) p[i]=P[1][i]=i; for(i=1;i<=m;i++) { cin>>x; e[make_pair(p[x],p[x+1])]=e[make_pair(p[x+1],p[x])]=1; swap(p[x],p[x+1]); } Bron_Kerbosch(1,0,n); cout<<ans<<endl; return 0; }
-
正解
总结
赛时以为保证 正确地加入决策集合需要换根分讨多种情况,没想到能直接把限制条件由儿子节点继承而来。 赛时瞪了 才发现每次赋值相互独立的性质。
后记
输出 即可通过此题。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18673623,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)