NOIP 模拟 8
1.CSP 模拟 02.CSP 模拟 13.CSP 模拟 24.CSP 模拟 35.CSP 模拟 46.CSP 模拟 57.CSP 模拟 68.CSP 模拟 79.CSP 模拟 810.CSP 模拟 911.CSP 模拟 1012.CSP 模拟 2413.CSP 模拟 2514.CSP 模拟 2615.CSP 模拟 2716.CSP 模拟 2817.CSP 模拟 2918.CSP 模拟 3019.CSP 模拟 3120.CSP 模拟 3221.CSP 模拟 3322.CSP 模拟 3423.CSP 模拟 3524.CSP 模拟 3625.CSP 模拟 3726.CSP 模拟 3827.CSP 模拟 3928.CSP 模拟 4029.CSP 模拟 4130.CSP 模拟 4231.CSP 模拟 4332.CSP 模拟 4433.CSP 模拟 4534.CSP 模拟 4635.CSP 模拟 4736.CSP 模拟 4837.CSP 模拟 4938.CSP 模拟 5039.CSP 模拟 5140.CSP 模拟 5241.CSP 模拟 5342.CSP 模拟 5443.NOIP 模拟 144.NOIP 模拟 245.NOIP 模拟 346.NOIP 模拟 447.NOIP 模拟 548.NOIP 模拟 649.NOIP 模拟 7
50.NOIP 模拟 8
51.NOIP2024(欢乐)加赛 352.NOIP 模拟 953.NOIP 模拟 1054.NOIP 模拟 1155.NOIP 模拟 1256.NOIP 模拟 1357.NOIP 模拟 1458.NOIP 模拟 1559.NOIP 模拟 1660.NOIP 模拟 17A 星际联邦
直接贪,对于每个点,连前缀 max
,后缀 min
,再把前缀 max
和后缀 min
连,直接跑 kruskal
就行,因为对
正解是无脑菠萝,维护不在同一连通块的最值和次值就行。
#include<bits/stdc++.h> #define int long long #define fi first #define se second #define pii std::pair<int,int> #define eb emplace_back #define pb push_back typedef long long ll; typedef unsigned long long ull; std::mt19937 myrand(std::chrono::high_resolution_clock::now().time_since_epoch().count()); inline int R(int n){return myrand()%n+1;} inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;} const int N=3e5+10,inf=1e18; inline void Min(int &x,int y){if(x>y)x=y;} inline void Max(int &x,int y){if(x<y)x=y;} int n,tot,a[N],ans; struct BINGCHAJI{ int fa[N],size[N]; inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} inline void merge(int x,int y){x=find(x),y=find(y);if(size[x]>size[y])std::swap(x,y);fa[x]=y;} }d; struct weihu{ int w1,u1,w2,u2; inline void merge_max(int w,int u){ if(!u1){w1=w,u1=u;return;} if(w>w1){if(u!=u1)w2=w1,u2=u1;w1=w,u1=u;return;} if(!u2){w2=w,u2=u;return;} if(w>w2&&u!=u1){w2=w,u2=u;return;} } inline void merge_min(int w,int u){ if(!u1){w1=w,u1=u;return;} if(w<w1){if(u!=u1)w2=w1,u2=u1;w1=w,u1=u;return;} if(!u2){w2=w,u2=u;return;} if(w<w2&&u!=u1){w2=w,u2=u;return;} } }; struct bian{ int v,w; inline void merge(int v1,int w1){if(w1<w||!v)v=v1,w=w1;} }b[N]; inline void Boruvka(){ for(int i=1;i<=n;++i)b[i]={0,inf}; weihu max={0,0,0,0},min={0,0,0,0}; for(int i=2;i<=n;++i){ max.merge_max(a[i-1],d.find(i-1)); if(max.u1&&max.u1!=d.find(i))b[d.find(i)].merge(max.u1,a[i]-max.w1); if(max.u2&&max.u2!=d.find(i))b[d.find(i)].merge(max.u2,a[i]-max.w2); } for(int i=n-1;i;--i){ min.merge_min(a[i+1],d.find(i+1)); if(min.u1&&min.u1!=d.find(i))b[d.find(i)].merge(min.u1,min.w1-a[i]); if(min.u2&&min.u2!=d.find(i))b[d.find(i)].merge(min.u2,min.w2-a[i]); } for(int i=1;i<=n;++i)if(d.find(i)==i&&b[i].v&&d.find(b[i].v)!=i){ ans+=b[i].w,d.merge(b[i].v,i),tot++; } } signed main(){ freopen("star.in","r",stdin);freopen("star.out","w",stdout); std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0); n=read();for(int i=1;i<=n;++i)a[i]=read(),d.fa[i]=i,d.size[i]=1; while(tot<n-1)Boruvka();std::cout<<ans<<'\n'; }
B 和平精英
傻逼题,首先必要条件是,popcount
大于答案的为与,小于的为或,等于的看情况分配,枚举答案的 popcount
,然后用线段树或者 st
表维护相关信息就行了,注意 popcount
相等的值也要相等,没有大于的看能不能用等于的分配,具体来说,就是维护区间大于等于小于的数量和并和与,然后各种判断。
#include<bits/stdc++.h> #define fi first #define se second #define pii std::pair<int,int> #define eb emplace_back #define pc __builtin_popcount #define pb push_back typedef long long ll; typedef unsigned long long ull; std::mt19937 myrand(std::chrono::high_resolution_clock::now().time_since_epoch().count()); inline int R(int n){return myrand()%n+1;} inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;} const int N=2e5+10,mod=998244353,inf=1e9; inline void Min(int &x,int y){if(x>y)x=y;} inline void Max(int &x,int y){if(x<y)x=y;} int n,a[N],Q,st[3][35][N][2],c[N],s[3][N]; bool ans[N]; struct QU{int l,r;}q[N]; inline void init(int w){ for(int i=1;i<=n;++i){ s[0][i]=s[0][i-1]+(c[i]<w);s[1][i]=s[1][i-1]+(c[i]==w);s[2][i]=s[2][i-1]+(c[i]>w); for(int j=0;j<3;++j)st[j][0][i][0]=INT_MAX,st[j][0][i][1]=0; int cur=(c[i]==w?1:(c[i]<w?0:2)); st[cur][0][i][0]=st[cur][0][i][1]=a[i]; } for(int i=0;i<3;i++) for(int j=1;(1<<j)<=n;j++) for(int k=1;k+(1<<j)-1<=n;k++){ st[i][j][k][0]=st[i][j-1][k][0]&st[i][j-1][k+(1<<j-1)][0]; st[i][j][k][1]=st[i][j-1][k][1]|st[i][j-1][k+(1<<j-1)][1]; } } inline int query(int t,int l,int r,int op){ int k=std::__lg(r-l+1);int lq=st[t][k][l][op],rq=st[t][k][r-(1<<k)+1][op]; return op?(lq|rq):(lq&rq); } signed main(){ freopen("peace.in","r",stdin);freopen("peace.out","w",stdout); std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0); n=read(),Q=read();for(int i=1;i<=n;++i)a[i]=read(),c[i]=pc(a[i]); for(int i=1;i<=Q;++i)q[i].l=read(),q[i].r=read(); for(int w=0;w<=30;++w){ init(w); for(int i=1;i<=Q;++i){ int l=q[i].l,r=q[i].r; if(l==r)continue; if(s[1][r]==s[1][l-1]){ if(s[0][r]==s[0][l-1])continue; if(s[2][r]==s[2][l-1])continue; ans[i]|=(query(0,l,r,1)==query(2,l,r,0)); continue; }// 没有相等的,直接判 int val=query(1,l,r,0); if(val!=query(1,l,r,1))continue;// 处理相等的不同情况 int vl=query(0,l,r,1),vr=query(2,l,r,0); if((vl|val)!=val||(vr&val)!=val)continue;// 判断与相等的子集补集关系 if((vl!=val||s[0][l-1]==s[0][r])+(vr!=val||s[2][l-1]==s[2][r])<=s[1][r]-s[1][l-1])ans[i]=1;//看相等的能否分配 } } for(int i=1;i<=Q;i++)puts(ans[i]?"YES":"NO"); }
C 摆烂合唱
建表达式树,然后设
- 如果当前符号为
&
,则这个儿子的概率等于另一个儿子为 的概率,这个点为 的概率等于两个儿子都为 的概率。 - 如果当前符号为
^
,则这个儿子的概率为 ,这个点为 的概率直接算。 - 如果当前符号为
|
,也相应算即可。
最后每个点到根的乘积就是答案。
D 对称旅行者
妙妙题,首先转成期望的形式,最后再乘上方案数就是答案,
然后人类智慧地设出一个
#include<bits/stdc++.h> #define int __int128 #define fi first #define se second #define pii std::pair<int,int> #define eb emplace_back #define pb push_back typedef long long ll; typedef unsigned long long ull; std::mt19937 myrand(std::chrono::high_resolution_clock::now().time_since_epoch().count()); inline int R(int n){return myrand()%n+1;} inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;} const int N=2e5+10,mod=1e9+7,inf=1e9; inline void Min(int &x,int y){if(x>y)x=y;} inline void Max(int &x,int y){if(x<y)x=y;} int n,m,K,g[N],p[N],x[N],ans[N],zc[N],f[N]; inline int qpow(int a,int b){int res=1;for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;return res;} inline void huan(int *a,int *b){ for(int i=1;i<n;++i)zc[i]=a[b[i]]; for(int i=1;i<n;++i)a[i]=zc[i]; } inline void QP(){ for(int i=1;i<n;++i)p[i]=i,ans[i]=i; for(int i=1;i<=m;++i)std::swap(p[x[i]],p[x[i]-1]); for(;K;K>>=1,huan(p,p))if(K&1)huan(ans,p); for(int i=1;i<n;++i)p[i]=ans[i]; for(int i=1;i<n;++i)ans[i]=g[p[i]]; } signed main(){ freopen("travel.in","r",stdin);freopen("travel.out","w",stdout); std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0); n=read();for(int i=1;i<=n;++i)f[i]=read(); for(int i=1;i<n;++i)g[i]=f[i+1]-f[i]; m=read(),K=read();for(int i=1;i<=m;++i)x[i]=read();int mul=qpow(2,m*K);QP(); for(int i=2;i<=n;++i)f[i]=f[i-1]+ans[i-1];for(int i=1;i<=n;++i)std::cout<<(ll)(((f[i]*mul)%mod+mod)%mod)<<' '; }
总结
妈的,T1 想到正解忘了再连一条边,T2 感觉不该不会,T3 不会就是纯傻逼,T4 不会暴力就是纯傻逼。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!