首页 > 其他分享 >梦熊十三连测第三场题解

梦熊十三连测第三场题解

时间:2024-07-29 09:42:39浏览次数:12  
标签:连通 int 题解 复杂度 siz 梦熊 2n 第三场 dis

T1

本题考察了数论的相关知识。

30pts

暴力枚举每次洗牌的情况,时间复杂度为 \(O(n^2)\)。

60pts

首先卡牌 \(1\) 和 \(2n\) 一直不动,可以不用考虑这两张牌。

将位置和剩下的牌上的数字全减 \(1\),那么数字为 \(k\) 的牌操作一次后就会到 \(2k\bmod (2n-1)\) 的位置。

那么问题相当于找最小的 \(k\) 使得 \(\forall t,t\times 2^{k}\equiv t\pmod {(2n-1)}\),显然只需要考虑 \(2^{k}\equiv 1\pmod {(2n-1)}\)​ 就行了,\(O(n)\) 暴力检验即可。

100pts

根据欧拉定理,\(k\) 必然是 \(\varphi(2n-1)\) 的因数,而 \(10^{18}\) 范围内的正整数的约数个数大约只有 \(10^6\) 级别,直接暴力快速幂判定就能过了。

输入的数会有点大。快读,开__int128

#include <bits/stdc++.h>
using namespace std;
#define int __int128
int n, m, p, t, e;
int T;
template<typename type>
inline void read(type &x)
{
    x=0;static bool flag(0);char ch=getchar();
    while(!isdigit(ch)) flag=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    flag?x=-x:0;
}

template<typename type>
inline void write(type x,bool mode=1)//0为空格,1为换行
{
    x<0?x=-x,putchar('-'):0;static short Stack[50],top(0);
    do Stack[++top]=x%10,x/=10; while(x);
    while(top) putchar(Stack[top--]|48);
    mode?putchar('\n'):putchar(' ');
}

int phi(int x) {
    int _p = x;
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0) {
            _p -= _p / i;
            while (x % i == 0) x /= i;
        }
    }
    if (x > 1)
        _p -= _p / x;
    return _p;
}
int ksm(int x, int y, int mod) {
    int a = x % mod;
    int ans = 1;
    while (y) {
        if (y & 1)
            ans *= a, ans %= mod;
        a *= a, a %= mod;
        y >>= 1;
    }
    return ans;
}
signed main() {
	freopen("card.in", "r", stdin);
	freopen("card.out", "w", stdout);
    read(T);
    while (T--) {
    	read(n);
        n = n - 1;
        m = 2 * n + 1;
        p = phi(m);
        t = p;
        e = sqrt((long long) p);
        for (int i = 1; i <= e; i++) {
			if(p%i!=0)continue;
            if (ksm(2, i, m) == 1) {
                t = i;
                break;
            }
			else {
                if (ksm(2, p / i, m) == 1)
                    t = p / i;
            }
        }
        write(t);
    }
    // fclose(stdin);
    // fclose(stdout);
    return 0;
}

T2

本题考察了图论的相关知识。

30pts

直接爆搜每次的情况并进行去重,时间复杂度为 \(O(n!)\),后续会给出具体证明。

+30pts

令初始的异或和为 \(x\),拿在手中,相当于每次用手中的数把 \(a\) 中的一个值顶掉,然后把原来的值拿在手里,这也间接说明了状态数是 \(n!\) 量级的。

此档分会发现 \(a_i\) 和所有 \(a_i\) 异或后的权值两两不同,我们考虑一个过程,用 \(x\) 替换了 \(a_p\),然后用 \(a_p\) 替换了 \(a_q\),循环下去。

其实最终一定是要用 \(b_i\) 替换 \(a_i\) 的,而上面的过程又是从 \(x\) 出发走了一条路,按如上方式建图找出环的个数即可统计答案。

100pts

我们从 \(b_i\) 向 \(a_i\) 连边(不同位置上相同的数值对应同一个点),然后尝试从 \(x\) 出发遍历每条边。

注意如果图是一个包含 \(x\) 的连通块,则一定可以找到一条欧拉路径(不一定是回路)覆盖所有边。

如果图不连通,或 \(x\) 在连通块内(\(x\) 不是孤立点),则答案就是边数再加上连通块数再减去 \(1\)(如果 \(x\) 是孤立点就不用减 \(1\))。

时间复杂度为 \(O(n)\)。

T3

本题考察了树的直径,二分图的相关知识。

10pts

爆搜所有 \(2^n\) 种情况,求最远点对距离即可。

40pts

考虑把 \(O(n^2)\) 对点对依次取出排好序,考虑如果答案 \(<x\),意味着所有点对距离 \(\geq x\) 的点对颜色必须两两不同,把这些约束取出,相当于一个二分图染色的问题,于是我们可以很方便的算出 \(<x\) 的答案,利用差分即可算出 \(=x\) 的答案。

100pts

先求出一条直径,若直径的两个端点颜色相同,则最长距离一定为直径。否则,令两个端点分别为 \(x,y\),并钦定 \(x,y\) 不同色。枚举答案 \(d\),所有到 \(x\) 距离 \(>d\) 的点颜色必须与 \(y\) 一样,所有到 \(y\) 距离 \(>d\) 的点颜色必须和 \(x\) 一样。由于 \(x,y\) 是直径的两个端点,可以发现,若一个点 \(z\) 到 \(x,y\) 的距离都不超过 \(d\),则其到任何一个点的距离不超过 \(d\),所以 \(z\) 的颜色并不会对答案产生影响。

所以,定义 \(cnt_i\) 表示到直径两端的距离不超过 \(i\) 的点数。定义 \(f_d\) 表示答案不超过 \(d\) 的树的形态数,\(g_d\) 表示答案为 \(d\) 的树的形态数,\(dis_{1/2}\) 表示从直径的两端点出发到其他点的距离。定义 \(L=\max(\min(dis_{1i}, dis_{2i}))\)。此处 \(L\) 的意义为,在所有形态的树中,最小的答案(同色点对最大距离)。对于每个点取到直径两端点近的那个颜色即可。

最终的总权值为 \(\sum_{i=L}^{S} g_i \times i\)。

容易得到 \(f_d = 2^{cnt_d}\)。但是我们想要答案等于 \(d\) 的树的形态数 \(g_i\)。很明显,只需要容斥减去 \(f_{d-1}\) 即可,也就是 \(g_d = f_d - f_{d-1}\)。

注意 \(x,y\) 共有 2 种颜色分配方案。

T4

本题考察了贪心的相关知识。

40pts

显然最终经过了 \(2k+dis(1,n)\) 条边,因此 \(n≡dis(1,n)( \bmod2)\) 就合法,否则不合法。

先考虑最小值,即只经过 \(path(1,n)\) 的方案。

那么对于路径上第 \(i\) 个点 \(c_i\),设他在路径外的子树大小为 \(siz(c_i)\)。

我们发现很多操作都要在折返中抵消,那么我们只要钦定链上哪些操作最终有用,剩下的操作形成若干跨子树的匹配,那么我们一定能构造一个合法的 \(p\)。

根据经典结论,那么我们要求剩下的操作中不存在绝对众数。

找到最大的 \(siz(c_i)\),那么我们至多在他的子树里钦定 \(i\) 个没被抵消。

因此这种情况的充要条件就是 \(siz(c_i)−i≤2n−dis(1,n)\),显然这样的 \(i\) 至多一个,因此我们能构造出一个合法的匹配。

否则找到不合法的这棵子树,枚举一个连通块 \(S\),记每个连通块内节点 \(u\) 在连通块外的子树大小为 \(siz(u)\)。

那么我们依然要求 \(siz(u)−i≤2n−dis(1,n)\),证明大致同上。

那么我们要在这个基础上保留尽可能少的节点是的所有 \(siz(u)\) 不超过 \(k=2n−dis(1,n)+i\)。

问题就变成:给一棵 \(n\) 顶点的树,可以断掉若干的边,要求断掉的边连通且连通块包含 \(1\) 节点。要求剩下每个连通块大小不超过 \(k\),求最小分割数,可以进行树形DP求解这个值,时间复杂度为 \(O(n^2)\)。

+10pts

考虑整张图为菊花图,所以除了 \(1\) 号点以外的地位相同,可以把除 \(n\) 号点的以外的点两两抵消,按照 \(n\) 的奇偶性进行分类讨论即可。

100pts

注意到 \(siz(c_i)≤n−dis(1,n)≤2k\),因此不合法的所有点构成一条链,对于每个点贪心地割掉若干个最大的子树即可。

时间复杂度 \(O(n \log n)\),如果利用桶排序,时间复杂度为 \(O(n)\)。

标签:连通,int,题解,复杂度,siz,梦熊,2n,第三场,dis
From: https://www.cnblogs.com/-y-0-x-0-h-/p/18329403

相关文章

  • Maximum Glutton题解
    正常动规,但是赛时死了。分析看到\(n\)很小,但是\(X\)和\(Y\)有点大,所以状态稍微改变一下。设\(dp_{i,j}\)表示已经选到第\(j\)个,且甜度为\(i\)时咸度的最小值。转移方程为:\[dp_{j,k}=\min_{0\lek\lei,a_i\lej\leX}(dp_{j,k},dp_{j-a_i,k-1}+b_i)\]按照\(i,j......
  • CF526G Spiders Evil Plan 题解
    Description给定一棵\(n\)个节点的无根树,每条边有边权。有\(q\)次询问,每次询问给出\(x,y\),你需要选择\(y\)条树上的路径,使这些路径形成一个包含\(x\)的连通块,且连通块中包含的边权和最大。\(n,q\le10^5\),强制在线。Solution考虑只有一组询问怎么快速求答案。容......
  • 【科大讯飞笔试题汇总】2024-07-27-科大讯飞秋招提前批(研发岗)-三语言题解(Cpp/Java/
    ......
  • ABC364 DEF 题解
    ABC364DEF题解D-K-thNearest题目链接赛时想了一个(也许确实是对的)做法,但是代码太难写,一直没写出来……看了官方题解才发现正解其实也很简单……本题最关键的一点是要转换思路:与其考虑“离某个点第\(k\)近的点在哪”,不如考虑“离某个点距离不超过\(x\)的点有多少个”。......
  • 会员购项目面试题解析:高效数据抓取与异常处理
    会员购项目亮点日志记录信息协程异步抓取数据,大大提高抓取速度捕获异常,并添加重试机制源码importloggingimporttimeimportrequestsimportasyncioimportaiohttpfromaiohttpimportContentTypeErrorimportcsv#配置日志logging.basicConfig(level=logging......
  • C++题解(17) 狐猬编程: 640.线段覆盖
    题目描述在一条数轴上,有N条线段,第i条线段的左端点是s[i],右端点是e[i]。如果线段有重叠(即使是端点重叠也算是重叠),则输出“impossible”,如果没有重叠则输出“possible”。输入格式输入文件名:640.in多组测试数据。第一行,一个整数G,表示有G组测试数据。1<=G<=10。每组......
  • [题解]ABC364 A~F
    A-GluttonTakahashi给定\(n\)道菜,每道菜要么是甜的(用sweet表示),要么是咸的(用salty表示)。必须按顺序吃,如果连续吃到\(2\)个甜的菜,就会浑身难受吃不下去了。请问是否能吃完这些菜。按题意模拟即可,只要前\(n-1\)个元素中有连续的sweet就输出No。点击查看代码#include<bits/s......
  • CF292D 题解
    \(O(mk\alpha(n))\)暴力,考虑对于每个询问\(l,r\),枚举\(1\siml-1,r+1\simm\),并查集连边即可。1154ms。\(O(n(m+k\alpha(n)))\)我们发现枚举\(i\in[1,l),j\in(r,m]\)太慢了。考虑先预处理出并查集从\(1\)连边到编号为\(id\)的边的状态\(pre_{id}\),倒过来再处理出......
  • CF626G Raffles 题解
    Description有\(n\)个奖池,第\(i\)个奖池的奖金是\(p_i\),已经有\(l_i\)张彩票押在上面。现在你有\(t\)张彩票,你需要将你的彩票分配到这些奖池中,并且保证你在每个奖池中押的彩票数不能超过该奖池原有的彩票数。若你在第\(i\)个奖池中押了\(t_i\)张彩票,则你中奖的概......
  • AtCoder Beginner Contest 363 题解 A-D(待补充)
    A-PilingUp1.1思路其实就是向上取百位的整,需要增加多少,123则为200-123=177;1.2代码voidsolve(){intn;cin>>n;intt=n/100;cout<<(t+1)*100-n;}B-JapaneseCursedDoll 2.1思路就是判断最少需要多少天,会有大于等于P个人......