首页 > 其他分享 >题解:P11132 【MX-X5-T4】「GFOI Round 1」epitaxy

题解:P11132 【MX-X5-T4】「GFOI Round 1」epitaxy

时间:2024-10-14 19:14:49浏览次数:1  
标签:排列 锚定 P11132 epitaxy 题解 times ge 答案 公因数

Problem Link

【MX-X5-T4】「GFOI Round 1」epitaxy

题目描述

给你两个正整数 \(n, m\)。

定义一个 \(1 \sim n\) 的排列 \(p\) 的价值为所有的 \(n - m + 1\) 个长度为 \(m\) 的连续子串内最大值的最大公因数。(规定单个数的最大公因数为其自身。)

请你求出一个在所有 \(1 \sim n\) 的排列中价值最大的排列,如果有多个,求出任意一个均可。

Solution

观察样例,有一发现:

最大值的最大公因数(最大值的公因数以下成为“答案”)一定是 \(n\) 的因数。

证明:

不论怎么排列,\(n\) 一定会出现在那 \(n-m+1\) 个子串中,所以最大的答案一定是 \(n\) 的因数。

那么,能不能确定答案的值呢?

由于要使答案最大,所以我们考虑对于一个 \(n\) 的因数,判断能否构造出排列,设一个排列的答案为 \(k\),发现对于一个答案 \(k\),在排列中对 \(k\) 产生贡献数字越少越好,所以产生贡献的数的下标一定是 \(m\) 的正整数倍,最少需要 \(n/m\) 个数去产生贡献。

对 \(k\) 产生贡献的值一定是 \(k\) 的正整数倍,且因为答案是最大值的公因数,所以放在相应位置的数的值依次为 \(n\),\(n-k\),\(n-2 \times k\),以此类推,能给出最多 \(n/k\) 个数去产生贡献。

下面一行代表下标,上面一行代表值。

发现判断能否构造出答案 \(k\),当且仅当 \(\frac{n}{k} \ge \frac{n}{m}\) 即 \(m \ge k\) 时。

所以最大的答案显然为:

  • 小于等于 \(m\) 且为 \(n\) 的因数的最大正整数。

那么我们可以用 \(O(m)\) 的复杂度找到 \(k\),怎么构造呢?

其实非常简单,在锚定那 \(\frac{n}{m}\) 个数之后把剩下的 \(n-\frac{n}{m}\) 个数从大到小依次排列下去即可。

为什么呢?

设我们构造到了第 \(i\) 个锚定数和第 \(i+1\) 个锚定数之间,则两数值分别为 \(n-(i-1) \times k\) 和 \(n-i \times k\),构造的数值域为 $\left [ n-(i+1) \times m, n-i \times m\right ] $。

因为 \(m \ge k\),

所以 \(-i \times k \ge -i \times m\),

所以 \(n-(i-1) \times k > n-i \times k \ge n-i \times m > n-(i+1) \times m\)。

所以构造的数永远小于锚定的数,区间最大值依旧是锚定值,答案不变。

那么代码便呼之欲出了。

代码

// written by Naught
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define Maxn 1000005
#define fo(i, l, r) for (int i = l; i <= r; ++i)
#define fr(i, r, l) for (int i = l; i >= r; --i)
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21], *p1 = buf, *p2 = buf;
inline int read(int x=0, bool f=0, char c=getchar()) {for(;!isdigit(c);c=getchar()) f^=!(c^45);for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48);return f?-x:x;}

int n, m, ans[Maxn];
bool t[Maxn];

int main()
{
    int _ = read();
    while (_--)
    {
        n = read(), m = read();
        fo(i, 1, n) ans[i] = 0, t[i] = true;
        int k = 1, num = n/m, tmp = 0;

        // 找 k
        fr(i, 1, m) if(n % i == 0) {k = i; break;} 

        // 构造序列
        fo(i, 1, num) ans[i*m] = n-tmp*k, t[n-tmp*k] = false, ++tmp;
        int i = 1, j = n;
        while(i <= n)
        {
            if(ans[i]) {++i; continue;}
            if(!t[j]) {--j; continue;}
            ans[i] = j, t[j] = false;
        }

        fo(i, 1, n) printf("%d%c", ans[i], " \n"[i==n]);
    }
    return 0;
}

标签:排列,锚定,P11132,epitaxy,题解,times,ge,答案,公因数
From: https://www.cnblogs.com/naughty-naught/p/18464790

相关文章

  • 题解:P9137 [THUPC 2023 初赛] 速战速决
    ProblemLink[THUPC2023初赛]速战速决题目描述题意清晰,不再过多赘述。Solution每张不同的卡是等效的。小\(J\)手上的卡牌只有\(2\)种情况:手上没有相同的牌和有相同的牌。情况\(1\):小\(J\)手上的牌等价于\(1\simn\)(但其实没用),令其手上的牌为\(b_1,b_2,\ldo......
  • 题解:P6299 差别
    ProblemLink差别题目描述给定\(a,b,c,d\),求\(p,q,r,s\)使得\(M\)成为非零最小值。Solution\(M\)的表达式很复杂,把式子拆开有\(16\)个\(4\)次项,不难发现这是一个平方和,不断套平方和公式,最后化简成:\[M=|(ap+bq+cr-ds)^2+(-aq+bp+cs+dr)^2|=((a+bi)\times(......
  • 题解:P9743 「KDOI-06-J」旅行
    ProblemLink「KDOI-06-J」旅行题意题目讲的很清楚,不再过多赘述。Solution不难想到\(O(n^2\timesm^2\timesk)\)的做法:定义\(f_{i,j,val,x,y}\)为当前在\((x,y)\)的位置,花费\(val\)元,手上有\(x\)张\(L\)公司的票,\(y\)张\(Z\)公司的票的方案数,至于空间问题......
  • 题解:P1709 [USACO5.5] 隐藏口令 Hidden Password
    ProblemLink[USACO5.5]隐藏口令HiddenPassword题目描述求最小表示法的开头字母在原字符串的位置。Solution最小表示法板子,双指针解决即可。Code#include<iostream>#include<algorithm>#include<string.h>#include<cstring>#include<cmath>#include<cstdio>......
  • [PA2021] Od deski do deski 题解
    好题好题,难者不会会者不难,我是前者。实际上加入就可以合法的数是很好计算的。考虑现在所有前缀合法串后的字符实际上都可以满足条件。容易想到根据是否合法设置状态。设\(f_{i,j}/g_{i,j}\)表示现在填第\(i\)个数,有\(j\)个填了就合法的数,现在的串合法/不合法。那么有转......
  • 题解:P11145 Strange Homura Game
    ProblemLinkStrangeHomuraGame题意让你猜测一个数\(n\),你只能输出两次,每次输出一个数\(x\),返回\(x\bmodn\)。Solution令输入的数为\(A,B\),输出的数为\(a,b\),答案为\(n\)。一开始想的是CRT,但只能询问\(2\)次。发现输入的值是经过\(\bmodn\)的,已知\((A-a)......
  • 题解:AT_joi2021ho_b 雪玉 (Snowball)
    ProblemLink[JOI2021Final]雪玉题目描述翻译很简洁,不作赘述。Solution对于相邻的两个雪球\(a_i\)和\(a_{i+1}\),两者夹着的区间中的雪要么是被\(a_i\)或\(a_{i+1}\)卷起,要么不可能被清理掉。那么思路非常简单了,对于每个区间,只有\(2\)种情况:区间左侧雪球的最......
  • 题解:P2315 [HNOI2005] 数三角形
    ProblemLink[HNOI2005]数三角形题意输入一个大三角形的各个边存在情况,输出里面有多少个正三角形。Solution简单暴力即可,用\(4\)个数组维护每条边能延伸的最大长度,然后逐个判断三角形是否可行即可。如图,l_upper维护左端点向上(即$\ell_{BA}$),l_lower维护左端点向下(即......
  • 题解:AT_arc120_c [ARC120C] Swaps 2
    ProblemLink[ARC120C]Swaps2\(-1\)的情况判错卡了\(10\)几分钟,麻了。题面翻译给出\(2\)个序列\(a\)和\(b\),定义一次操作为:选定一个下标\(i\),先将\(a_i\)以及\(a_{i+1}\)交换,然后让\(a_i\)加一,最后让\(a_{i+1}\)减一。求最少操作次数使得\(a\)序列等......
  • 题解:[HNOI2009] 双递增序列
    ProblemLink[HNOI2009]双递增序列题目描述给定一个长度为\(n\)的序列(\(n\)为偶数),求是否可以把序列分成\(2\)个长度为\(\frac{n}{2}\)的递增序列。Solution首先想到定义\(f_i\)为一个序列以\(a_i\)结尾时另一个序列末尾最小值。但这样定义状态信息是不够的,考虑......