10.4 - 11.4 改题纪要

10.4 - 11.4 改题纪要

还是决定写一起。

等写完了就会把问号改了

冲刺CSP联训模拟2

以后见了计数先想容斥!!!

  1. T1 挤压

    按位拆开,每两位一块考虑,枚举每个数是否选,O(nlog2n) 的。

  2. T2 工地难题

    考虑恰好比较难做,先前缀和变成至少。

    发现 0 个数一定,其将序列分成若干小段,每段有若干 1

    相当于是 xi=k(xi<k) 的形式,直接容斥即可。

  3. T3 星空遗迹

    首先发现点显然的性质。

    • 连续一段的长度无意义。
    • 如果一段中两端(如果只有一端就是一端)都是能赢他的,就可以删掉这一段。
    • 依次删掉后一定只剩下一段相同的。

    由此可以有单调栈写法,保证任意一个非栈顶元素一定会输给其下一个(也可写逆天并查集,但好像不太好扩展到正解)。

    考虑修改。

    对于每个元素,维护栈在加入它后的大小,设其为 fi

    fi={fi+1si<si1i=1fisi=si1max(fi1,1)si>si1

    最后的答案就是最后一个为 1 的位置

    发现这个 max 很难整,考虑直接去掉,发现其相当于是连续下降,容易证明有一个好的性质:只有最小值和最后一个 1 一一对应。

    但其实也不用特意找最后一个,考虑升降是对称的,所以栈大小相同的元素一定是一样的。

    维护单点改,前缀和的区间 min,可以直接上线段树上二分,也可以前缀和变成区间加,区间 min

  4. T4 纽带

    析合树上 dp,这是我现在能改的???

多校A层冲刺NOIP2024模拟赛03

两签一原(虽然原不是都做过,但是也是签)。

  1. T4 量子隧穿问题(experiment):

    挺好的题,@wang54321 不要因为你实现屎就说题屎。

    发现记录有没有猫的方案数比较麻烦,这里我们记录概率。

    显然基环树,先考虑只是一棵树怎么做,考虑设 dpi,j 表示第 i 时刻 j 的概率,依次枚举边转移即可,转移就是考虑猫是否转移。

    发现有环就挂了,因为考虑若 p(p<1) 的概率有猫,1p 的概率没猫,在环上转移一圈时每一个都对 p 有依赖,在最后转移到起点时就会将依赖有猫和依赖没猫的结合,导致错误。

    可能可以通过逆天小技巧进行最后一步转移,但这里介绍比较简单的钦定。

    考虑题解做法,钦定第一条边的左右端点来断边,钦定其在跳环前是 1,10,11,00,0 分讨,最后乘上其概率即可。

    发现 0,11,0 在跳第一次之后一模一样,可以只分讨三种。

    考虑有冲突的关键是依赖有猫和依赖没猫的概率的冲突,只钦定环上第一次跳的点即可,只用分讨两种。

csp-s模拟9

accoders 的模拟赛出过了,于是有了这个代替,不是我们 csp/noip 模拟赛出两道 UNR 是吧。

  1. T1 邻面合并

    发现 m 很小,直接用 vector 状压即可。

    也可以压二进制,发现对于每一层那些地方会有矩形是固定的,状态只是分割点,可以 28 压起来。

  2. T2 光线追踪

    考虑横线和竖线互不影响,分开考虑。

    每条线对应一个斜率范围,离散化后就是区间推 min,单点查。

    注意边界。

  3. T3 百鸽笼

    好题,单开了一篇 this

  4. T4 滑稽树下你和我

    计算几何,没准会改。

    真的改了。

    首先需要知道怎么求点到线段距离,考虑先点积判断是否垂足在线段上,用叉积的模除以底来求垂线长。

    可以看 this

    二分答案。

    首先有结论,如果在两个点在两条线段一端时满足,在另一端时也满足,则一定有满足要求的一种移动。

    证明就是发现将一条线段放平,另一条一定时单调的。

    于是在特殊性质时可以直接枚举两个点来转移。

    考虑在非特殊性质时,会有一个点在一条边上等另一个,考虑将边变成点,由于有结论,在最优时一定是等的点在离另一个点最近的点上,直到另一个点到达是其依然在最近的点上。

    形如:

    形如(图不咋地,凑合吧)

    考虑将边变成点,其和其他点的距离就是点到直线距离,可以直接转移,但有小常数的做法,设 dpi,j 表示一个点在 i 边上,另一个在 j 点上是否可行,发现其也可以表示所有情况。

    放个代码吧
    #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

  1. T4 表达式:

    首先观察性质,发现除了暴力以外所有模数都可以分解成较小的互质数相乘。

    直接线段树维护值域套 CRT 合并即可。

多校A层冲刺NOIP2024模拟赛06

  1. T3 一个真实的故事:

    首先发现值域很小,考虑直接用线段树维护,合并的时候暴力将左边最靠右和右边最靠左的不同 k 个归并扫描线即可。

    有和值域无关的做法,可以看 this马上就写写了)

  2. T4 异或区间(xor):

    经典结论:对于每个值所管辖的 max 区间中左边和右边较小的一边的和是 nlogn 级的。

    证明可以考虑笛卡尔树。

    于是有两种做法,一是用可持久化 trie 每次遍历较小区间,一是建笛卡尔树跑启发式。

csp-s模拟11

不是非多校的题这么难。(断句:不是、非多校的题这么难?)

  1. T3 暴雨:

    考虑对于两边都漏的显然是不好整,考虑枚举前 k 大来作为最大的分割左右(比它大的直接铲掉)。

    考虑只有一边要枚举,设 dpi,j,k 表示当前在 i,挖了 k 下,前面最高的是 k,暴力转移是 O(n2k) 的,但是发现最高的只有可能是前 k 大,于是可以做到 O(nk2),总复杂度 O(nk3)

    有个简单的实现是将第三维保留 n 的大小,将第一维滚掉优化空间,这样不用下标的重编号。

    当我们写出 dp 后,我们发现枚举前 k 大纯唐,可以直接将前缀后缀用一个拼起来转移,不用每次重做一遍,复杂度变为 nk2

  2. T2 AVL 树:

    根据前序遍历或中序遍历贪心即可,因为树高是 log 的每次暴力跳爹来更新右子树最少选的个数,细节不少。

  3. T4 置换:

    首先是置换环经典结论,其次数等于 lcm{}

    考虑 dp,设 dpi,j 表示以 i 为环长,jlcm 的概率,枚举长度和个数转移即可,用方案数的乘上 lcm2,注意在最后除掉 n!

    map 轻松 60pts,考虑优化。

    发现对于一个 n 的因子,其最大次数是一,先提出来,dp 完放回即可。

  4. T5 传统题:

    是个好题,先放这提醒我改。

多校A层冲刺NOIP2024模拟赛07

  1. T3 距离(distance):

    首先用树形 dp 经典结论,每次合并子树用 szu×szv(这里 szu 是已经合并的子树大小)总复杂度 n2,证明考虑每个点对只会在 lca 处有 1 的贡献。

    但正解和这个没关系。

    考虑 minmax 容斥,将 max|xaxb|,|yayb| 也就是切比雪夫距离转曼哈顿距离,问题就变成了求解四个不相关的绝对值。

    暴力可以树状数组套 dsu on tree,用巴雷特约减可以卡过 accoder,过不了学校 oj。

    可以直接用值域线段数,类似 cdq 统计左区间对右区间的贡献,线段树合并即可。

  2. T4 团队选拔(selection):

    考虑一个 n3 做法:设 dpi,j 表示前缀是 igcdj 的方案数,最后枚举一遍 aigcd 转移即可。

    发现显然结论,每个数为起点的所有区间的 gcd 的种类数是 log 级别的,n 个数就是 nlogn 级别的。

    于是我们用栈处理出每个数前后缀区间的 gcd 种类所对应的左右端点区间,具体的就是每次加入时将当前栈遍历一遍,和这个数取 gcd 后合并相同区间,显然任意时刻栈的大小是 log 级的。

    然后枚举每个 gcd,总共有用的转移点一共就 nlogn 个,对于没有转移点的直接区间推平,用线段树维护,答案是区间加,差分即可。

多校A层冲刺NOIP2024模拟赛08

  1. T3 战场模拟器 (simulator) :

    考虑每个人只会死一次,盾也只有一次贡献,用线段树维护区间 min 暴力改即可(也可以用分块微调快长)。

  2. T4 点亮 (light) :

    首先经过转换题意,发现其每个联通块都是一个重边加上一些边组成的树,联通块个数就是重边个数。

    容斥,设 g(x) 表示钦定(至少) x 条重边的方案数。

    不太显然的是:

    g(x)=n!2x(n2i)!j=1x1(n2)(n2j2)

    解释就是在 后面的部分是钦定选的边求概率,考虑从大到小按边权加边,将 j 理解为从 x1 可能好理解一点, 前面的部分是在选这 x 条边(式子约了一个 i!)。

csp-s模拟12

  1. T3 小 y 的数论

    先考虑全局,这个是简单的,显然取长剖后的前 k 长链即可。

    考虑区间,显然可以直接推到虚树上,考虑合并,对于 k=2 时其有优秀性质:直径可以合并,类似的,我们猜测 k>2 时也有可以合并的性质,其实确实有,证明也比较显然,考虑每次必然取的时长链端点,而端点又一定是之前的端点。

    于是有了好做法,ST 表维护,合并时对于左右各 k 个点建虚树,长剖求答案,查询时依然这样合并。

    稍微分析一下复杂度就知道,根本过不去!

    考虑分块来平衡复杂度,每 K 个分一块,块间维护 ST 表,最后将散块暴力合并即可。

  2. T4 小j 的组合

    是签,想不到吧。

    考虑复制一个点等价于让一个点的经过次数 +1,考虑树上的哈密顿路就是 dfs 一遍,发现只有一条链可以只经过一遍,于是就是找直径板子。

多校A层冲刺NOIP2024模拟赛09

  1. T1 排列最小生成树

    不是,nnlogn 过不去 5×104 啊啊啊!

    首先发现边权 >n 的点对一定不会选,因为显然从 1 连到 n 连一条链就没有边权 >n

    发现两个点能连当且仅当 |ij|<=n|pipj|<=n,其一共只有 nn 对,最后桶排跑最小生成树即可。

  2. T4 区间 (interval)

    首先离线,将询问离线到右端点,扫描线。

    考虑如何维护第一个限制,用单调栈即可。

    考虑第二个限制,直接上线段树,于是变成了区间历史和板子。

多校A层冲刺NOIP2024模拟赛10

  1. T3 TG393. 列表

    this(罕见的提前写好了)

后面的基本都是逆天区分度,不写了。

也许会把几个不太逆天的单改一下。

好像还有一道『T5 传统题』没改,别急,一定会改的。

完结撒花!!正好一个月

P


posted @   5k_sync_closer  阅读(82)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示