2023年石门中学NOIP模拟测试(2023.10.12)
又被打爆...
T1
签到。竖着和斜着差分一下,最后从左往右扫一遍做完。
T2
做不出来这个显得很弱智...其实可以将整个游戏看成二叉树,然后每次的分左右儿子取决于
考虑优化之:结论就是他不可能递归超过
Code
#include<bits/stdc++.h> #define il inline #define rint register int #define int long long using namespace std; const int N=2e5+10,INF=2147483647; char *p1,*p2,buf[N]; #define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++) #define gc() getchar() il int rd(){ int x=0,f=1; char ch=gc(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=gc();} while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=gc(); return x*f; } int n,m; int a[N],b[N]; int tot,rt; int ls[N<<5],rs[N<<5],sum[N<<5]; void ins(int &p,int dep,int val){ if(!p)p=++tot; if(dep>m){sum[p]+=val;return;} ins((val%b[dep])?ls[p]:rs[p],dep+1,val); } int query(int p,int dep){ if(!p)return 0; if(dep>m)return sum[p]; int L=query(ls[p],dep+1),R=query(rs[p],dep+1); return (dep&1)?min(L,R):max(L,R); } void Main(){ n=rd(),m=rd(); if(m>30){cout<<0;return;} for(int i=1; i<=n; ++i)a[i]=rd(); for(int i=1; i<=m; ++i)b[i]=rd(); for(int i=1; i<=n; ++i)ins(rt,1,a[i]); cout<<query(rt,1); } signed main(){ freopen("game.in","r",stdin); freopen("game.out","w",stdout); int T=1; while(T--)Main(); return 0; }
T3
这题挂成狗显得我很菜...怎么挂的呢?oh,妈妈我
这题直接连边显然不可行,那我们不妨将其转化成每个同时和约数的虚点连接,这样同样有连通性。
于是这样建图复杂度就变为了
然后来考虑图中删除一个点对连通块的影响,显然只有割点才有影响,我们跑
Code
#include<bits/stdc++.h> #define il inline #define ll long long #define re register using namespace std; il int read(){ int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*f; } const int N=4e6+10,M=1e7+10; int n; int a[N]; int pr[M],pi[M],tot_pr,tot; bool vis[M]; int id[N]; void pre(){ for(int i=2; i<M; ++i){ if(!vis[i]){ pr[++tot_pr]=i; pi[i]=i; } for(int j=1; j<=tot_pr&&pr[j]*i<M; ++j){ vis[i*pr[j]]=1; pi[i*pr[j]]=pr[j]; if(i%pr[j]==0)break; } } tot=0; for(int i=2; i<M; ++i)if(vis[i]&&!vis[i/pi[i]])id[i]=++tot; } struct Edge{ int to,nxt; }e[M]; int tot_e,head[N]; void add_e(int x,int y){ e[++tot_e]={y,head[x]}; head[x]=tot_e; } bool v[N]; int S; void dfs(int x){ v[x]=1; if(x<=n)++S; for(int i=head[x]; i; i=e[i].nxt){ int y=e[i].to; if(v[y])continue; dfs(y); } } int dfn[N],low[N],cnt,rt,siz[N],top,st[N],Ans; void Tarjan(int x){ dfn[x]=low[x]=++cnt; st[++top]=x;siz[x]=0; int g=0,ans=0; for(int i=head[x]; i; i=e[i].nxt){ int y=e[i].to; if(!dfn[y]){ Tarjan(y); low[x]=min(low[x],low[y]); if(low[y]>=dfn[x]){ ++g; int z,s=0; do{ z=st[top--]; siz[x]+=siz[z];s+=siz[z]; }while(z!=y); ans=max(ans,s); } }else{ low[x]=min(low[x],dfn[y]); } } if(x<=n){ ++siz[x]; if(g>1&&x==rt||g)Ans=min(Ans,max(ans,S-siz[x])); } } void init(){ tot_e=0; memset(head,0,sizeof(head)); memset(v,0,sizeof(v)); cnt=top=0; memset(dfn,0,sizeof(dfn)); } void Main(){ n=read(); for(int i=1; i<=n; ++i)a[i]=read(); for(int i=1; i<=n; ++i){ int p[20]={0},t[20]={0}; while(a[i]>1){ int q=pi[a[i]]; p[++p[0]]=q; while(a[i]%q==0)a[i]/=q,++t[p[0]]; } for(int j=1; j<=p[0]; ++j){ for(int k=j+(t[j]<=1); k<=p[0]; ++k){ if(p[j]*p[k]<M){ int v=id[p[j]*p[k]]+n; add_e(i,v),add_e(v,i); } } } } int ma=0,mma=0,p; for(int i=1; i<=n; ++i){ if(!v[i]){ S=0; dfs(i); // cout<<S<<'s'<<endl; if(S>=ma)mma=ma,p=i,ma=S; else mma=max(mma,S); } } rt=p; Ans=ma-1; S=ma; Tarjan(p); cout<<max(Ans,mma)<<endl; } int main(){ freopen("connect.in","r",stdin); freopen("connect.out","w",stdout); int T=read(); pre(); while(T--)init(),Main(); return 0; }
T4
原题面:
简化题面:
数据范围:
原题是
我的评价是:比较套路,但是我不会。
首先两条路径不好搞,考虑先固定一条,选择另一条的方案数。我们设
再记录
本文作者:J1mmyF-blog
本文链接:https://www.cnblogs.com/J1mmyF-blog/p/17760397.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步