NOIP2024(欢乐)加赛3
1.高一上十一月上旬日记2.NOIP2024加赛13.多校A层冲刺NOIP2024模拟赛184.NOIP2024加赛25.多校A层冲刺NOIP2024模拟赛196.多校A层冲刺NOIP2024模拟赛20
7.NOIP2024(欢乐)加赛3
8.高一上十一月中旬日记9.NOIP2024加赛410.多校A层冲刺NOIP2024模拟赛2111.2025--炼石计划-- 11 月 13 日 --NOIP 模拟赛 #2012.NOIP2024加赛513.NOIP2024加赛614.多校A层冲刺NOIP2024模拟赛2415.高一上十一月下旬日记16.多校A层冲刺NOIP2024模拟赛2517.NOIP2024加赛718.2025--炼石计划-- 11 月 23 日 --NOIP 模拟赛 #2319.【MX-S7】梦熊 NOIP 2024 模拟赛 3 & SMOI Round 2(同步赛)20.多校A层冲刺NOIP2024模拟赛2621.NOIP2024加赛822.多校A层冲刺NOIP2024模拟赛27终结篇NOIP2024(欢乐)加赛3
CF2033B Sakurako and Water
-
枚举主对角线取
即可。点击查看代码
ll a[510][510]; int main() { ll t,n,ans=0,maxx,i,j,k,h; cin>>t; for(h=1;h<=t;h++) { cin>>n; ans=0; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cin>>a[i][j]; } } for(k=-n+1;k<=n+1;k++) { maxx=0; for(i=1,j=i+k;i<=n;i++,j++) { if(i<=n&&1<=j&&j<=n&&a[i][j]<0) { maxx=max(maxx,-a[i][j]); } } ans+=maxx; } cout<<ans<<endl; } return 0; }
CF2025B Binomial Coefficients, Kind Of
-
观察样例加打表可知,
即为所求。- 已知递推式
,省去 的状态后有 。 能更新到的值只有 ,故 即为所求。
点击查看代码
const ll p=1000000007; ll n[100010],m[100010],C[1010][1010]; 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; } int main() { ll t,i; cin>>t; for(i=1;i<=t;i++) { cin>>n[i]; } for(i=1;i<=t;i++) { cin>>m[i]; if(m[i]==n[i]) { cout<<1<<endl; } else { cout<<qpow(2,m[i],p)<<endl; } } return 0; }
- 已知递推式
CF2030D QED's Favorite Permutation
-
对于移动,我们可以无脑进行交换来保证移动,然后将中途交换的位置再交换回去。
-
通过手摸不难发现,
能移动到 当且仅当 中不含有LR
子串。 -
反向考虑,即
LR
子串不被上述区间包含,差分判断即可。点击查看代码
ll a[200010],d[200010]; char s[200010]; int main() { ll t,n,m,x,sum,i,j; cin>>t; for(j=1;j<=t;j++) { cin>>n>>m; sum=0; for(i=1;i<=n;i++) { cin>>a[i]; d[min(a[i],i)]++; d[max(a[i],i)]--; } for(i=1;i<=n;i++) { d[i]+=d[i-1]; } cin>>(s+1); for(i=1;i<=n-1;i++) { if(s[i]=='L'&&s[i+1]=='R') { sum+=(d[i]!=0); } } for(i=1;i<=m;i++) { cin>>x; if(s[x]=='L') { s[x]='R'; if(x+1<=n&&s[x+1]=='R') { sum-=(d[x]!=0); } if(x-1>=1&&s[x-1]=='L') { sum+=(d[x-1]!=0); } } else { s[x]='L'; if(x+1<=n&&s[x+1]=='R') { sum+=(d[x]!=0); } if(x-1>=1&&s[x-1]=='L') { sum-=(d[x-1]!=0); } } if(sum!=0) { cout<<"No"<<endl; } else { cout<<"Yes"<<endl; } } for(i=1;i<=n;i++) { d[i]=0; } } return 0; }
CF2025E Card Game
-
部分分
:输出样例。
-
正解
- 对于除了花色为
的卡牌中,Alice
选择的卡牌数量必须Bob
选择的卡牌数量。即若设 表示花色为 的卡牌Alice
/Bob
选择的卡牌数量,则有 。 - 设
表示同种花色,前 大等级的卡牌中Alice
多拿了 张牌且双方都没有多余的牌的方案数,状态转移方程为 。边界为 。 - 设
表示 花色中Bob
一共多拿了 张牌且双方都没有多余牌的方案数,状态转移方程为 ,边界为 。 - 最终,有
即为所求,可以使用矩阵快速幂加速。
点击查看代码
const ll p=998244353; ll f[2][510],g[2][510]; int main() { // #define Issac #ifdef Issac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ll n,m,ans=0,i,j,k; cin>>n>>m; f[0][0]=1; for(i=1;i<=m;i++) { for(j=0;j<=i;j++) { f[i&1][j]=f[(i-1)&1][j+1]; if(j-1>=0) { f[i&1][j]=(f[i&1][j]+f[(i-1)&1][j-1])%p; } } } g[1][0]=1; for(i=2;i<=n;i++) { for(j=0;j<=m;j++) { g[i&1][j]=0; for(k=0;k<=j;k++) { g[i&1][j]=(g[i&1][j]+g[(i-1)&1][k]*f[m&1][j-k]%p)%p; } } } for(i=0;i<=m;i++) { ans=(ans+f[m&1][i]*g[n&1][i]%p)%p; } cout<<ans<<endl; return 0; }
- 对于除了花色为
CF1967D Long Way to be Non-decreasing
-
部分分
- 考虑从
向 连一条有向边,那么 能到达的点就是经过若干次操作后可以成为的值。 - 答案上界显然为
,考虑二分答案。 时求出令 走至多 步能到达的范围内不小于 的数 ,主席树空间开不下遂写了暴力。
- 考虑从
点击查看代码
int a[1000010],b[1000010],vis[1000010],tot=0; vector<int>e[1000010],s[1000010]; void dfs(int x,int rt) { s[rt].push_back(x); vis[x]=tot; for(int i=0;i<e[x].size();i++) { if(vis[e[x][i]]!=tot) { dfs(e[x][i],rt); } } } bool check(int mid,int n,int m) { int last=0,minn; for(int i=1;i<=n;i++) { minn=0x7f7f7f7f; for(int j=0;j<s[a[i]].size()&&j<=mid;j++) { if(s[a[i]][j]>=last) { minn=min(minn,s[a[i]][j]); } } last=minn; if(last==0x7f7f7f7f) { return false; } } return true; } int main() { int testcase,n,m,l,r,mid,ans,i,j; scanf("%d",&testcase); for(j=1;j<=testcase;j++) { scanf("%d%d",&n,&m); for(i=1;i<=m;i++) { e[i].clear(); s[i].clear(); vis[i]=0; } for(i=1;i<=n;i++) { cin>>a[i]; } for(i=1;i<=m;i++) { cin>>b[i]; e[i].push_back(b[i]); } for(i=1;i<=m;i++) { tot++; dfs(i,i); } l=0; r=m; ans=-1; while(l<=r) { mid=(l+r)/2; if(check(mid,n,m)==true) { ans=mid; r=mid-1; } else { l=mid+1; } } printf("%d\n",ans); } return 0; }
-
正解
- 考虑双指针枚举最终的
,判断 走至多 步能否到达。 - 建反图方便断边后跑
。特殊分讨下有向基环树上两点间的距离即可。
点击查看代码
int a[1000010],b[1000010],dep[1000010],col[1000010],pos[1000010],rt[1000010],dfn[1000010],out[1000010],low[1000010],ins[1000010],cnt,tim,scc_cnt,tot,len; vector<int>e[1000010],scc[1000010]; stack<int>s; void tarjan(int x) { tim++; dfn[x]=low[x]=tim; ins[x]=1; s.push(x); for(int i=0;i<e[x].size();i++) { if(dfn[e[x][i]]==0) { tarjan(e[x][i]); low[x]=min(low[x],low[e[x][i]]); } else { if(ins[e[x][i]]==1) { low[x]=min(low[x],dfn[e[x][i]]); } } } if(dfn[x]==low[x]) { scc_cnt++; int k=0; while(x!=k) { k=s.top(); ins[k]=0; col[k]=scc_cnt; scc[scc_cnt].push_back(k); s.pop(); } } } void dfs(int x,int fa,int root) { tot++; dfn[x]=tot; rt[x]=root; dep[x]=dep[fa]+1; for(int i=0;i<e[x].size();i++) { if(col[e[x][i]]==0&&e[x][i]!=fa) { dfs(e[x][i],x,root); } } out[x]=tot; } int get_dis(int x,int y) { if(x==y) { return 0; } if(col[x]==0&&col[y]==0) { return (rt[x]==rt[y]&&dfn[y]<=dfn[x]&&dfn[x]<=out[y])?dep[x]-dep[y]:0x7f7f7f7f; } if(col[x]!=0&&col[y]!=0) { if(col[x]==col[y]) { return (pos[x]>pos[y])?pos[x]-pos[y]:pos[x]+(int)scc[col[x]].size()-pos[y]; } else { return 0x7f7f7f7f; } } if(col[x]==0) { int tmp=dep[x]; x=rt[x]; if(col[x]==col[y]) { if(pos[x]==pos[y]) { return tmp; } return (pos[x]>pos[y])?tmp+pos[x]-pos[y]:tmp+pos[x]+(int)scc[col[x]].size()-pos[y]; } else { return 0x7f7f7f7f; } } else { return 0x7f7f7f7f; } } bool check(int mid,int n,int m) { for(int i=1,j=1;i<=n;i++) { while(j<=m&&get_dis(a[i],j)>mid) { j++; } if(j>m) { return false; } } return true; } void bfs(int x,int co) { len++; pos[x]=len; for(int i=0;i<e[x].size();i++) { if(col[e[x][i]]==co&&pos[e[x][i]]==0) { bfs(e[x][i],co); } } } int main() { #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif int t,n,m,l,r,mid,ans,i,j,k; scanf("%d",&t); dep[0]=-1; for(k=1;k<=t;k++) { scanf("%d%d",&n,&m); for(i=1;i<=scc_cnt;i++) { scc[i].clear(); } cnt=tim=scc_cnt=tot=0; while(s.empty()==0) { s.pop(); } for(i=1;i<=m;i++) { e[i].clear(); col[i]=dep[i]=rt[i]=dfn[i]=low[i]=ins[i]=pos[i]=0; } for(i=1;i<=n;i++) { cin>>a[i]; } for(i=1;i<=m;i++) { cin>>b[i]; e[b[i]].push_back(i); } for(i=1;i<=m;i++) { if(dfn[i]==0) { tarjan(i); } } for(i=1;i<=m;i++) { if(scc[col[i]].size()==1&&b[i]!=i) { col[i]=0; } } for(i=1;i<=scc_cnt;i++) { if(scc[i].size()!=1) { for(j=0;j<scc[i].size();j++) { dfs(scc[i][j],0,scc[i][j]); } len=0; bfs(scc[i][0],i); } } for(i=1;i<=m;i++) { if(b[i]==i&&scc[col[i]].size()==1) { dfs(i,0,i); len=0; bfs(i,col[i]); } } l=0; r=m; ans=-1; while(l<=r) { mid=(l+r)/2; if(check(mid,n,m)==true) { ans=mid; r=mid-1; } else { l=mid+1; } } printf("%d\n",ans); } return 0; }
- 考虑双指针枚举最终的
CF2023D Many Games
-
部分分
:爆搜。 :背包。
点击查看代码
const double eps=1e-8; ll p[200010],w[200010]; double ans=0; unordered_map<ll,double>f; unordered_map<ll,double>::iterator itt; set<ll,greater<ll> >s; set<ll,greater<ll> >::iterator it; vector<ll>tmp; int main() { ll n,i; cin>>n; s.insert(0); f[0]=1; for(i=1;i<=n;i++) { cin>>p[i]>>w[i]; for(it=s.begin();it!=s.end();it++) { if(f.find(w[i]+*it)==f.end()) { f[w[i]+*it]=f[*it]*p[i]/100.0; } else { f[w[i]+*it]=max(f[w[i]+*it],f[*it]*p[i]/100.0); } tmp.push_back(w[i]+*it); } while(tmp.empty()==0) { s.insert(tmp.back()); tmp.pop_back(); } } for(itt=f.begin();itt!=f.end();itt++) { if((double)itt->first*itt->second-ans>eps) { ans=(double)itt->first*itt->second; } } printf("%.8lf\n",ans); return 0; }
-
正解
- 首先先特判掉
的情况。 - 设
。对于 能加入集合 当且仅当 ,即 ,得到 的上界为 。 - 对于同一个
一定优先选择 比较大的物品,不妨先对其降序排序。类似的,设同一个 已经选择了前 大的物品,能继续选择第 大的物品当且仅当 ,又因为 有 ,联立得到 ,即 ,于是只有前 个数才可能成为最优解。
点击查看代码
double f[200010]; vector<ll>v[110]; vector<pair<ll,ll> >e; int main() { // #define Issac #ifdef Issac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ll n,p,w,sum=0,i,j,k; double ans=0; cin>>n; for(i=1;i<=n;i++) { cin>>p>>w; if(1<=p&&p<=99) { v[p].push_back(w); } sum+=(p==100)*w; } for(i=1;i<=99;i++) { sort(v[i].begin(),v[i].end(),greater<ll>()); k=i/(100-i); for(j=0;j<v[i].size()&&j<=k;j++) { e.push_back(make_pair(i,v[i][j])); } } f[0]=1; for(i=0;i<e.size();i++) { for(j=200000;j>=e[i].second;j--) { f[j]=max(f[j],f[j-e[i].second]*e[i].first/100.0); } } for(i=0;i<=200000;i++) { ans=max(ans,1.0*(sum+i)*f[i]); } printf("%.8lf\n",ans); return 0; }
- 首先先特判掉
总结
的部分分没来得及写。- 以为最终连成的一个环,破环为链后分前后缀考虑,然后就口胡了个假的势能线段树维护在线二维数点。基本全场都在写
。 - 需要特殊处理的部分想清楚再调,找基环树和求基环树上两点距离调了一个下午、一个晚上没调出来,但第二天想清楚后半小时就调完了。
- 以为最终连成的一个环,破环为链后分前后缀考虑,然后就口胡了个假的势能线段树维护在线二维数点。基本全场都在写
后记
- 貌似
是拿他的公号交的,可能是学校 远端评测比赛的初试(?)。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18538477,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2023-11-10 【学习笔记】数学知识-组合计数