首页 > 其他分享 >2024暑假集训测试11

2024暑假集训测试11

时间:2024-07-25 20:45:11浏览次数:6  
标签:11 int void Tp 凸包 2024 tfrac 集训 define

前言

image

这次好多外校的参加 \(60\) 多个人,反正至少没怎么挂分。

确切的说赛时我只能冲 T1、T2,T3 可撤销或可持久化并查集都不会,赛后现学的,T4 更抽象,可惜 T2 打假了。T3 最后五分钟才开始看,没想直接打暴力了。

但是 T3 数据太水了,加了捆绑还是水,赛后安排了重测。

T1 Permutations & Primes

  • 同名原题。

一个区间合法必须有 \(1\),所以把 \(1\) 放中间,然后将 \(2,3\) 放到两端即可,这样只要过 \(1\) 的区间除了原序列答案一定为 \(2\) 或 \(3\),而原序列结果是无法更改的。

T2 树上游戏

  • 原题:ARC116E Spread of InformationP3523 [POI2011] DYN-Dynamite……

    弱化版:P3942 将军令P2279 [HNOI2003] 消防局的设立(不用二分)……

  • 部分分 \(10pts\):爆搜。

  • 部分分 \(29pts\):当 \(k\ge \lfloor\dfrac{n}{2}\rfloor\) 时,答案为 \(1\)。

  • 正解:

    先来看 P3942 将军令 这道题,是一个树形 DP,要求每个点到关键点的距离不超过 \(k\)。

    定义 \(f_{x,1}\) 为 \(x\) 到其子树中最远的一个没有被覆盖到的节点的距离,\(f_{x,0}\) 为 \(x\) 到其最近一个关键点的距离。

    首先若 \(f_{x,1}+f_{x,0}\le k\) 说明改棵子树都被覆盖到了,\(f_{x,1}=-1\) 即可。

    从贪心的角度,若 \(f_{x,1}=k\) 时,将 \(x\) 设为关键点,正确性是显然的,这样能在使其子树全部被覆盖的同时覆盖更多点,则此时 \(f_{x,1}=-1,f_{x,0}=0\) 即可。

    最后发现根节点是处理不到的,特判其有没有被覆盖,没有就在根节点设立关键点。

    发现本体存在单调性,二分答案其距离 \(k\) 即可。

    点击查看代码
    #include<bits/stdc++.h>
    #define ll long long 
    #define endl '\n'
    #define sort stable_sort
    using namespace std;
    const int N=2e5+10,inf=1e9;
    template<typename Tp> inline void read(Tp&x)
    {
        x=0;register bool z=true;
        register char c=getchar();
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
        for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        x=(z?x:~x+1);
    }
    template<typename Tp> inline void wt(Tp x)
    {if(x>9)wt(x/10);putchar((x%10)+'0');}
    template<typename Tp> inline void write(Tp x)
    {if(x<0)putchar('-'),x=~x+1;wt(x);}
    int n,k,ans,f[N][2];
    vector<int>e[N];
    void dfs(int x,int fa,int mid)
    {
        f[x][0]=inf,f[x][1]=0;
        for(int y:e[x])
        {
            if(y==fa) continue;
            dfs(y,x,mid);
            if(f[y][1]!=-1) f[x][1]=max(f[x][1],f[y][1]+1);
            f[x][0]=min(f[x][0],f[y][0]+1);
        }
        if(f[x][1]>=mid)
        {
            ans++;
            f[x][1]=-1;
            f[x][0]=0;
        }
        if(f[x][1]+f[x][0]<=mid) f[x][1]=-1;
    }
    signed main() 
    {
        read(n),read(k);
        for(int i=1,x,y;i<=n-1;i++)
        {
            read(x),read(y);
            e[x].push_back(y);
            e[y].push_back(x);
        }
        int l=1,r=n-1,answ;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            ans=0;
            memset(f,0,sizeof(f));
            dfs(1,0,mid);
            if(f[1][1]!=-1) ans++;
            if(ans<=k) r=mid-1,answ=mid;
            else l=mid+1;
        }
        write(answ);
    }
    

T3 Ball Collector

  • 同名原题。

  • 部分分 \(20pts\):爆搜即可。

  • 正解:

    经典的套路,将 \(a_i,b_i\) 进行连边,最后会出来很多连通块,其边数就是其可选的个数,每个块之间互不影响。

    发现若连通块为一棵树,最多选 \(size-1\) 个点,否则可以取 \(size\) 个点。

    考虑连边时的贡献,将两个块 \(x,y\) 连一条边,若其中存在至少一个是树的话,则其会变成图,贡献 \(+1\),否则没有贡献。

    可以使用可撤销并查集维护,这个玩意很好打,学一下就会了。

    然后还学了一下可持久化并查集,就是用类似于主席树维护并查集即可。

    点击查看代码
    #include<bits/stdc++.h>
    #define ll long long 
    #define endl '\n'
    #define sort stable_sort
    using namespace std;
    const int N=2e5+10;
    template<typename Tp> inline void read(Tp&x)
    {
        x=0;register bool z=true;
        register char c=getchar();
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
        for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        x=(z?x:~x+1);
    }
    template<typename Tp> inline void wt(Tp x)
    {if(x>9)wt(x/10);putchar((x%10)+'0');}
    template<typename Tp> inline void write(Tp x)
    {if(x<0)putchar('-'),x=~x+1;wt(x);}
    int n,f[N],sz[N],a[N],b[N],ans[N];
    vector<int>e[N];
    bool vis[N];
    int find(int x) {return f[x]==x?x:find(f[x]);}
    void dfs(int x,int fa,int sum)
    {
        ans[x]=sum;
        for(int y:e[x])
        {
            if(y==fa) continue;
            int fx=find(a[y]),fy=find(b[y]);
            if(sz[fx]<sz[fy]) swap(fx,fy);
            if(fx==fy)
            {
                if(!vis[fx])
                {
                    vis[fx]=1;
                    dfs(y,x,sum+1);
                    vis[fx]=0;
                }
                else dfs(y,x,sum);
            }
            else
            {
                int last=sz[fx];
                bool vx=vis[fx],vy=vis[fy];
                f[fy]=fx,sz[fx]+=sz[fy],vis[fx]|=vis[fy];
                if(!vx||!vy) dfs(y,x,sum+1);
                else dfs(y,x,sum);
                f[fy]=fy,sz[fx]=last,vis[fx]=vx,vis[fy]=vy;
            }
        }
    }
    signed main() 
    {
        read(n);
        for(int i=1;i<=n;i++) 
        {
            read(a[i]),read(b[i]);
            f[i]=i,sz[i]=1;
        }
        for(int i=1,x,y;i<=n-1;i++)
        {
            read(x),read(y);
            e[x].push_back(y);
            e[y].push_back(x);
        }
        if(a[1]==b[1]) vis[a[1]]=1;
        else f[b[1]]=a[1],sz[a[1]]+=sz[b[1]];
        dfs(1,0,1);
        for(int i=2;i<=n;i++) write(ans[i]),putchar(' '); 
    }
    

T4 满穗

抽象玩意,溜了溜了。

官方题解

设 \(p_i\) 表示 \([1, i]\) 内所有正整数的和, \(q_i\) 表示 \([1, i]\) 内所有负整数的和。

如果 \(i < j\) 并且 \(s_i < s_j\) ,那么有 \(\tfrac{p_i}{P} - \tfrac{q_i}{Q} < \tfrac{p_j}{P} - \tfrac{q_j}{Q}\) 。

简单移项有 \(\tfrac{p_i - p_j}{P} < \tfrac{q_i - q_j}{Q}\) 。

有 \(\tfrac{Q}{P} < \tfrac{q_i - q_j}{p_i - p_j}\) 。

发现是斜率的形式,并且 \(p\) 单调递增, \(q\) 单调递减,可以维护一个上凸包在上面二分斜率。

由于存在修改操作,我们无法维护整个序列的凸包,但是容易发现如果修改的位置为 \(i\) ,对于 \(j > i\) 和 \(j < i\) 的位置,它们的图包只发生了平移操作,其斜率未发生变化,因此考虑使用分块维护。

具体的,对序列分块,每个块内建出对应的凸包,修改操作直接将其对应块的凸包重构,其他凸包平移,查询操作,扫描整个凸包,二分找到最优点后对所有凸包取 \(\max\) 即可。

总结

没学过的知识点还是好多啊,甚至都影响模拟赛了,但是天天模拟赛又很少有时间过知识点。

T2 没想出来有点可惜,感觉差一点吧,分数就比较平凡,反正没挂分就是好的。

附录

本场比赛 rk1 可以找 chino 领取穗。

T4 游戏背景写得不错,直接剧透了某款游戏,这是 T4 的图:

image

这是属于 rk1 的奖励(学长画的太好了):

image

标签:11,int,void,Tp,凸包,2024,tfrac,集训,define
From: https://www.cnblogs.com/Charlieljk/p/18324071

相关文章

  • 河南萌新联赛2024第(二)场:南阳理工学院
    A-国际旅行Ⅰ因为保证联通,所以直接排序就好了#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingvi=vector<int>;i32main(){ intn,m,q; cin>>n>>m>>q; via(n); for(int&i:a)cin>>i; sort(a......
  • 【专题】2024年云计算白皮书报告合集PDF分享(附原数据表)
    原文链接:https://tecdat.cn/?p=371122023年全球云计算市场显著增长,预计将持续繁荣至2027年突破万亿美元,中国市场同样保持强劲势头,预计也将大幅跃升。国内云计算经过十余年发展,虽取得显著进展,但在资源布局、服务质量和技术融合等方面仍需深化提升。阅读原文,获取专题报告合集全文,解......
  • 平邑2024高算(补题)
    Day1risk题目描述解法考虑最后的集结,不妨考虑找出所有集结过程中可能经过的边,不难发现是一棵树,所以答案就是最小生成树。代码点击查看代码structnode{ intu,v,w;}e[3000001];intn,m;intfa[3000001];intfind(intx){ returnx==fa[x]?fa[x]:fa[x]=find(......
  • 2024 暑假友谊赛-热身2
    TreeDestruction-洛谷|计算机科学教育新生态(luogu.com.cn)思路:树的直径。定理:在一棵树上,从任意节点y开始进行一次DFS,到达的距离其最远的节点z必为直径的一端。第一次dfs1(),从任意一个点,到达的最远的点必然是直径两端的其中一个。再从找到的端点开始dfs1(),......
  • 郑州轻工业大学ZZULIOJ1111~1123合集
    郑州轻工业大学zzulioj1111~1123合集本人小趴菜一颗,写博客是为了监督自己的学习以及分享学习资源给需要的人,欢迎大家评论区指出问题。同时由于本人比较懒,注释就不再写了,当然一些自己经常犯迷糊的地方还是会标注的,大家有什么问题也可以指出来,大家一起学习进步。郑州轻......
  • NOIP2024/7/25模拟赛
    T4题意:答案对\(2^{16}\)取模。分析:根节点\(1\)选到\(1\)的概率为\(\frac{1}{n}\),然后随便把剩下的\(n-1\)分配给它的所有子树,记\(1\)的其中一个儿子为\(y\),那么\(y\)选到它所被分配到的数中最小值的概率为\(\frac{1}{siz_{y}}\),然后\(y\)再继续分配给它的子......
  • 河南萌新联赛2024第(二)场:南阳理工学院
    1.D-A*BBBB原题链接:https://ac.nowcoder.com/acm/contest/87255/D根据乘法的原理,且b的每一位都相同,最终答案则是错位相加得出的结果,于是我们将a翻转,从个位开始计算,如果当前位置小于a.size就往前累加,但如果大于或等于b.size就从头开始一个一个的减(这个过程可以通过纸上手写乘法计......
  • 2024.7.25(Git、gitlab以及分支管理)
    分布式版本控制系统一、Git概述Git是一种分布式版本控制系统,用于跟踪和管理代码的变更。它是由LinusTorvalds创建的,最初被设计用于Linux内核的开发。Git允许开发人员跟踪和管理代码的版本,并且可以在不同的开发人员之间进行协作。Github用的就是Git系统来管理它们的网......
  • Metasploit Pro 4.22.2-2024071901 (Linux, Windows) - 专业渗透测试框架
    MetasploitPro4.22.2-2024071901(Linux,Windows)-专业渗透测试框架Rapid7Penetrationtesting,releaseJul19,2024请访问原文链接:https://sysin.org/blog/metasploit-pro-4/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org世界上最广泛使用的渗透测试框架......
  • 11. 函数的参数
    1.函数的概念与定义1.1概念循环的本质:在相同的地方反复执行相同的代码函数的本质:在不同的地方反复执行相同的代码1.2语法def函数名(参数1,参数2):"""函数的注释"""函数体代码return返回值1.def:是定义函数的关键字2.函数名:函数名类似于变量名,指代......