10.4 - 11.4 改题纪要
10.4 - 11.4 改题纪要
还是决定写一起。
等写完了就会把问号改了
冲刺CSP联训模拟2
以后见了计数先想容斥!!!
-
T1 挤压
按位拆开,每两位一块考虑,枚举每个数是否选,
的。 -
T2 工地难题
考虑恰好比较难做,先前缀和变成至少。
发现
个数一定,其将序列分成若干小段,每段有若干 。相当于是
的形式,直接容斥即可。 -
T3 星空遗迹
首先发现点显然的性质。
- 连续一段的长度无意义。
- 如果一段中两端(如果只有一端就是一端)都是能赢他的,就可以删掉这一段。
- 依次删掉后一定只剩下一段相同的。
由此可以有单调栈写法,保证任意一个非栈顶元素一定会输给其下一个(也可写逆天并查集,但好像不太好扩展到正解)。
考虑修改。
对于每个元素,维护栈在加入它后的大小,设其为
:最后的答案就是最后一个为
的位置发现这个
很难整,考虑直接去掉,发现其相当于是连续下降,容易证明有一个好的性质:只有最小值和最后一个 一一对应。但其实也不用特意找最后一个,考虑升降是对称的,所以栈大小相同的元素一定是一样的。
维护单点改,前缀和的区间
,可以直接上线段树上二分,也可以前缀和变成区间加,区间 。 -
T4 纽带
析合树上
,这是我现在能改的???
多校A层冲刺NOIP2024模拟赛03
两签一原(虽然原不是都做过,但是也是签)。
-
T4 量子隧穿问题(experiment):
挺好的题,@wang54321 不要因为你实现屎就说题屎。
发现记录有没有猫的方案数比较麻烦,这里我们记录概率。
显然基环树,先考虑只是一棵树怎么做,考虑设
表示第 时刻 的概率,依次枚举边转移即可,转移就是考虑猫是否转移。发现有环就挂了,因为考虑若
的概率有猫, 的概率没猫,在环上转移一圈时每一个都对 有依赖,在最后转移到起点时就会将依赖有猫和依赖没猫的结合,导致错误。可能可以通过逆天小技巧进行最后一步转移,但这里介绍比较简单的钦定。
考虑题解做法,钦定第一条边的左右端点来断边,钦定其在跳环前是
、 、 、 分讨,最后乘上其概率即可。发现
和 在跳第一次之后一模一样,可以只分讨三种。考虑有冲突的关键是依赖有猫和依赖没猫的概率的冲突,只钦定环上第一次跳的点即可,只用分讨两种。
csp-s模拟9
accoders 的模拟赛出过了,于是有了这个代替,不是我们 csp/noip 模拟赛出两道 UNR 是吧。
-
T1 邻面合并
发现
很小,直接用vector
状压即可。也可以压二进制,发现对于每一层那些地方会有矩形是固定的,状态只是分割点,可以
压起来。 -
T2 光线追踪
考虑横线和竖线互不影响,分开考虑。
每条线对应一个斜率范围,离散化后就是区间推
,单点查。注意边界。
-
T3 百鸽笼
好题,单开了一篇 this
-
T4 滑稽树下你和我
计算几何,没准会改。真的改了。
首先需要知道怎么求点到线段距离,考虑先点积判断是否垂足在线段上,用叉积的模除以底来求垂线长。
可以看 this
二分答案。
首先有结论,如果在两个点在两条线段一端时满足,在另一端时也满足,则一定有满足要求的一种移动。
证明就是发现将一条线段放平,另一条一定时单调的。
于是在特殊性质时可以直接枚举两个点来转移。
考虑在非特殊性质时,会有一个点在一条边上等另一个,考虑将边变成点,由于有结论,在最优时一定是等的点在离另一个点最近的点上,直到另一个点到达是其依然在最近的点上。
形如:
形如(图不咋地,凑合吧)
考虑将边变成点,其和其他点的距离就是点到直线距离,可以直接转移,但有小常数的做法,设
表示一个点在 边上,另一个在 点上是否可行,发现其也可以表示所有情况。放个代码吧
#include<bits/stdc++.h> using namespace std; using llt=long long; using llf=long double; using ull=unsigned long long; #define endl '\n' #ifdef LOCAL FILE *InFile=freopen("in_out/in.in","r",stdin),*OutFile=freopen("in_out/out.out","w",stdout); #else FILE *InFile=stdin,*OutFile=stdout; #endif const double Eps=1e-8; int Cmp(double a,double b){return fabs(a-b)<Eps?0:(a<b?-1:1);} struct Pnt{double x,y; Pnt(){} Pnt(double a,double b):x(a),y(b){}}; double Dis(const Pnt &a,const Pnt &b){return sqrtl((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));} struct Vec{ double x,y; Vec(){} Vec(double a,double b):x(a),y(b){} Vec(const Pnt &a,const Pnt &b):x(b.x-a.x),y(b.y-a.y){} Vec &operator+=(const Vec &b){x+=b.x,y+=b.y; return *this;} Vec operator-()const{return Vec(-x,-y);} Vec &operator-=(const Vec &b){*this+=-b; return *this;} Vec operator+(const Vec &b)const{Vec ans=*this; return ans+=b;} Vec operator-(const Vec &b)const{Vec ans=*this; return ans-=b;} Vec &operator*=(double k){x*=k,y*=k; return *this;} friend Vec operator*(double k,Vec a){a*=k; return a;} Vec operator*(double k)const{return k*(*this);} double operator*(const Vec &b)const{return x*b.x+y*b.y;} double operator^(const Vec &b)const{return x*b.y-y*b.x;} }; struct Lin{ Pnt a,b; Lin(){} Lin(const Pnt &a1,const Pnt &a2):a(a1),b(a2){} Lin(double a1,double a2,double a3,double a4):a(a1,a2),b(a3,a4){} operator Vec()const{return Vec(a,b);} operator double()const{return Dis(a,b);} }; double Dis(const Pnt &p,const Lin &l){ if(Vec(l.a,p)*Vec(l.a,l.b)<0) return Dis(p,l.a); if(Vec(l.b,p)*Vec(l.b,l.a)<0) return Dis(p,l.b); return abs(Vec(l.a,l.b)^Vec(l.a,p))/double(l); } const int N=1003; struct Gph{ int hd[N],to[N<<1],nt[N<<1],wt[N<<1],tot=1; void Add(int u,int v,int w){wt[++tot]=w,to[tot]=v,nt[tot]=hd[u],hd[u]=tot;} void ADD(int u,int v,int w){Add(u,v,w),Add(v,u,w);} #define For_to(i,u,v,g) for(int i=g.hd[u],v=g.to[i];i;i=g.nt[i],v=g.to[i]) }g; int n,sa,sb,cd[N]; Pnt cp[N]; Lin cl[N]; bool dp[N][N]; bool Chk(double lim){ memset(dp,0,sizeof(dp)); queue<pair<int,int>> que; auto Lim=[&lim](double a){return Cmp(a,lim)<=0;}; For_to(i,sa,v,g) if(Lim(Dis(cp[sb],cl[g.wt[i]]))) dp[sb][g.wt[i]]=1,que.emplace(sb,i); For_to(i,sb,v,g) if(Lim(Dis(cp[sa],cl[g.wt[i]]))) dp[sa][g.wt[i]]=1,que.emplace(sa,i); while(!que.empty()){ auto tmp=que.front(); que.pop(); int p=tmp.first,l=tmp.second; if(cd[p]==1&&((cd[g.to[l]]==1&&Lim(Dis(cp[p],cp[g.to[l]])))||(cd[g.to[l^1]]==1&&Lim(Dis(cp[p],cp[g.to[l^1]]))))) return 1; For_to(i,p,v,g){ if(!dp[v][g.wt[l]]&&Lim(Dis(cp[v],cl[g.wt[l]]))) dp[v][g.wt[l]]=1,que.emplace(v,l); int np=g.to[l],nl=g.wt[i]; if(!dp[np][nl]&&Lim(Dis(cp[np],cl[nl]))) dp[np][nl]=1,que.emplace(np,i); np=g.to[l^1]; if(!dp[np][nl]&&Lim(Dis(cp[np],cl[nl]))) dp[np][nl]=1,que.emplace(np,i); } } return 0; } int main(){ ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr); cin>>n>>sa>>sb; cout<<fixed<<setprecision(10); for(int i=1;i<=n;++i) cin>>cp[i].x>>cp[i].y; for(int i=1;i<n;++i){int a,b; cin>>a>>b; cl[i]=Lin(cp[a],cp[b]),g.ADD(a,b,i),++cd[a],++cd[b];} double l=Dis(cp[sa],cp[sb]),r=2e6; for(int i=1;i<=40;++i){ double mid=(l+r)/2; if(Chk(mid)) r=mid; else l=mid; } cout<<l; }
多校A层冲刺NOIP2024模拟赛04
-
T4 表达式:
首先观察性质,发现除了暴力以外所有模数都可以分解成较小的互质数相乘。
直接线段树维护值域套 CRT 合并即可。
多校A层冲刺NOIP2024模拟赛06
-
T3 一个真实的故事:
首先发现值域很小,考虑直接用线段树维护,合并的时候暴力将左边最靠右和右边最靠左的不同
个归并扫描线即可。有和值域无关的做法,可以看 this(
马上就写写了) -
T4 异或区间(xor):
经典结论:对于每个值所管辖的
区间中左边和右边较小的一边的和是 级的。证明可以考虑笛卡尔树。
于是有两种做法,一是用可持久化 trie 每次遍历较小区间,一是建笛卡尔树跑启发式。
csp-s模拟11
不是非多校的题这么难。(断句:不是、非多校的题这么难?)
-
T3 暴雨:
考虑对于两边都漏的显然是不好整,考虑枚举前
大来作为最大的分割左右(比它大的直接铲掉)。考虑只有一边要枚举,设
表示当前在 ,挖了 下,前面最高的是 ,暴力转移是 的,但是发现最高的只有可能是前 大,于是可以做到 ,总复杂度 。有个简单的实现是将第三维保留
的大小,将第一维滚掉优化空间,这样不用下标的重编号。当我们写出
后,我们发现枚举前 大纯唐,可以直接将前缀后缀用一个拼起来转移,不用每次重做一遍,复杂度变为 。 -
T2 AVL 树:
根据前序遍历或中序遍历贪心即可,因为树高是
的每次暴力跳爹来更新右子树最少选的个数,细节不少。 -
T4 置换:
首先是置换环经典结论,其次数等于
。考虑
,设 表示以 为环长, 为 的概率,枚举长度和个数转移即可,用方案数的乘上 ,注意在最后除掉用
轻松 60pts,考虑优化。发现对于一个
的因子,其最大次数是一,先提出来, 完放回即可。 -
T5 传统题:
是个好题,先放这提醒我改。
多校A层冲刺NOIP2024模拟赛07
-
T3 距离(distance):
首先用树形
经典结论,每次合并子树用 (这里 是已经合并的子树大小)总复杂度 ,证明考虑每个点对只会在 处有 的贡献。但正解和这个没关系。
考虑
容斥,将 也就是切比雪夫距离转曼哈顿距离,问题就变成了求解四个不相关的绝对值。暴力可以树状数组套 dsu on tree,用巴雷特约减可以卡过 accoder,过不了学校 oj。
可以直接用值域线段数,类似 cdq 统计左区间对右区间的贡献,线段树合并即可。
-
T4 团队选拔(selection):
考虑一个
做法:设 表示前缀是 , 是 的方案数,最后枚举一遍 和 转移即可。发现显然结论,每个数为起点的所有区间的
的种类数是 级别的, 个数就是 级别的。于是我们用栈处理出每个数前后缀区间的
种类所对应的左右端点区间,具体的就是每次加入时将当前栈遍历一遍,和这个数取 后合并相同区间,显然任意时刻栈的大小是 级的。然后枚举每个
,总共有用的转移点一共就 个,对于没有转移点的直接区间推平,用线段树维护,答案是区间加,差分即可。
多校A层冲刺NOIP2024模拟赛08
-
T3 战场模拟器 (simulator) :
考虑每个人只会死一次,盾也只有一次贡献,用线段树维护区间
暴力改即可(也可以用分块微调快长)。 -
T4 点亮 (light) :
首先经过转换题意,发现其每个联通块都是一个重边加上一些边组成的树,联通块个数就是重边个数。
容斥,设
表示钦定(至少) 条重边的方案数。不太显然的是:
解释就是在
后面的部分是钦定选的边求概率,考虑从大到小按边权加边,将 理解为从 到 可能好理解一点, 前面的部分是在选这 条边(式子约了一个 )。
csp-s模拟12
-
T3 小 y 的数论
先考虑全局,这个是简单的,显然取长剖后的前
长链即可。考虑区间,显然可以直接推到虚树上,考虑合并,对于
时其有优秀性质:直径可以合并,类似的,我们猜测 时也有可以合并的性质,其实确实有,证明也比较显然,考虑每次必然取的时长链端点,而端点又一定是之前的端点。于是有了好做法,ST 表维护,合并时对于左右各
个点建虚树,长剖求答案,查询时依然这样合并。稍微分析一下复杂度就知道,根本过不去!
考虑分块来平衡复杂度,每
个分一块,块间维护 ST 表,最后将散块暴力合并即可。 -
T4 小j 的组合
是签,想不到吧。
考虑复制一个点等价于让一个点的经过次数
,考虑树上的哈密顿路就是 一遍,发现只有一条链可以只经过一遍,于是就是找直径板子。
多校A层冲刺NOIP2024模拟赛09
-
T1 排列最小生成树
不是,
过不去 啊啊啊!首先发现边权
的点对一定不会选,因为显然从 连到 连一条链就没有边权 。发现两个点能连当且仅当
或 ,其一共只有 对,最后桶排跑最小生成树即可。 -
T4 区间 (interval)
首先离线,将询问离线到右端点,扫描线。
考虑如何维护第一个限制,用单调栈即可。
考虑第二个限制,直接上线段树,于是变成了区间历史和板子。
多校A层冲刺NOIP2024模拟赛10
-
T3 TG393. 列表
后面的基本都是逆天区分度,不写了。
也许会把几个不太逆天的单改一下。
好像还有一道『T5 传统题』没改,别急,一定会改的。
完结撒花!!正好一个月
P
本文来自博客园,作者:5k_sync_closer,转载请注明原文链接:https://www.cnblogs.com/xrlong/p/18447058
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了