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

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

时间:2024-09-29 22:34:08浏览次数:9  
标签:P11132 epitaxy int 题解 最大值 long 倍数 区间 define

1.做法及证明

因为 \(n\) 一定会被包含在某一区间内,所以最后答案肯定是 \(n\) 的因数。

先给出结论:对于 \(n\) 的因数 \(d\),其合法的充要条件为 \(d\le m\),所以我们只需要找到第一个小于等于 \(m\) 的 \(d\) 即可。

接下来我们来证明。

下文用 \(i'\) 表示以第 \(i\) 位开头的长度为 \(m\) 的区间,\(p_i\) 同题意。

对于一个值 \(p_i\),其能影响到的 \(i'\) 为所有的 \(j',j\in[i-m+1,i]\)。我们称其管辖着区间 \([i-m+1,i]\)。当然越过边界的自动将左边界变为 \(1\)。

令 \(kd\) 表示最小的成为所管辖区间最大值的值。

显然的,我们需要由 \(d\) 的倍数来作为所有 \(i'\) 的最大值,而一个数可管辖的区间显然长度不超过 \(m\),如果 \(d>m\),那么就说明 \(kd\) 管辖的区间无法填入所有大于 \((k-1)d\) 的数,那么由 \((k-1)d\) 管辖的区间就一定会与某个大于其的数所管辖区间相交,那么一定存在 \(i'\) 的最大值不为 d 的倍数,不合法。

相反的,如果 \(d\le m\) 就一定不存在 \(i'\) 的最大值不为 d 的倍数,因为所有大于 \((k-1)d\) 的数都被填掉了。

知道以上几点就很好构造了,只要在 \(m\) 的倍数的位置,从大到小填入 \(d\) 的倍数,接着在空位从大到小填入剩下没填的数即可。

2.Code:

因为写的时候很难受,所以很丑,轻喷。

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define m_p make_pair
#define m_t make_tuple
#define N 1000010
using namespace std;
int a[N];
bitset<N> vis;
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T;
	int n, m, qn, d, x, fl, num;
	vector<int> p;
	cin >> T;
	while (T--)
	{
		cin >> n >> m;
		p.clear();
		qn = sqrt(n);
		for (int i = 1; i <= n; i++)
			a[i] = vis[i] = 0;
		for (int i = 1; i < qn; i++)
		{
			if (n % i)
				continue;
			p.push_back(i);
			p.push_back(n / i);
		}
		if (qn * qn == n)
			p.push_back(qn);
		else if (n % qn == 0)
		{
			p.push_back(qn);
			p.push_back(n / qn);
		}
		sort(p.begin(), p.end());
		for (int i = p.size() - 1; i >= 0; i--)
		{
			d = p[i];
			if (d <= m)
				break;
		}
		x = n;
		for (int i = m; i <= n; i += m)
		{
			a[i] = x;
			vis[x] = 1;
			x -= d;
		}
		x = n;
		for (int i = 1; i <= n; i++)
		{
			if (a[i])
				cout << a[i] << " ";
			else
			{
				while (vis[x])
					--x;
				cout << x << " ";
				--x;
			}
		}
		cout << "\n";
	}
	return 0;
}

人生中距离 AK 最近的一次,结果我没有把握好。

作为 J 组的最后一题,如果我当时写了对拍,或许结果就会不一样了。

标签:P11132,epitaxy,int,题解,最大值,long,倍数,区间,define
From: https://www.cnblogs.com/wryyy-233/p/18440885

相关文章

  • NEERC2014题解
    A结论题,行着取intn,m;signedmain(void){#ifdefONLINE_JUDGEfreopen("alter.in","r",stdin);freopen("alter.out","w",stdout);#endif read(n),read(m); writeln(n/2+m/2); for(inti=2;i<=n;i......
  • [USACO23JAN] Tractor Paths P 题解
    T4[USACO23JAN]TractorPathsP唯二的两道蓝题之一,但难度至少紫黑之间。思路是这篇题解的。首先一个贪心:跳到与当前区间相连的最靠右的区间肯定是最优的,由此倍增易得第一问。重点在于第二问的求解,我们发现这个东西很麻烦,这时候就需要一些寄巧了。具体来说,前人之述备矣。坑点:D......
  • 题解:AtCoder Beginner Contest AT_abc373_d ABC373D Hidden Weights
    题目传送门题目翻译给你一个NNN个点,MMM条边的有向图,其中边有边......
  • [2023四校联考3]sakuya 题解(根号分治)
    题目链接。题目分析第一个操作类似哈希冲突那一道题,可以运用类似的思路开一个二维表,很容易想到两种做法:开一个二维表,表上的第\(i\)行,第\(j\)列表示序列下标在模\(i\)意义下等于\(j\)的加法标记。对于修改操作,直接暴力修改对应的那一行的值即可,查询时用线段树查询那个......
  • 联考题解
    联考题解龙(dragon)难点:(1)删边后如何寻找新的最短路。(2)A,B两方的决策互相影响十分复杂。(3)如何统计每个起点的ans。解题:(3)解决这类多起点一终点的问题,可以想到dp。(1)解决这类最短路转移的问题,可以考虑最短路树。(2)解决这类博弈问题,可以设计两个dp数组,分别维护影响前后的ans,在转移......
  • [雅礼集训 2017 Day1]市场 题解
    题目链接题目分析听说是很典的一道题,很明显难点在于除法下取整的操作。类似花神那一道题,但是由于有区间加,所以无法进行暴力修改。很明显暴力复杂度爆炸,考虑下取整带来的性质:对于一对相邻的数,很明显有\(\lfloor\frac{x-1}{k}\rfloor\le\lfloor\frac{x}{k}\rfloor-1\)。......
  • i++和++i的区别,面试题解析
    i++和++i都是自增操作符,用于将变量的值增加1。i++是后增操作符,它首先返回变量的值,然后再将变量的值增加1。例如,如果i的初始值为1,执行i++后,i的值变为2。++i是前增操作符,它首先将变量的值增加1,然后再返回变量的值。例如,如果i的初始值为1,执行++i后,i的值变为2。区别在于返回值的......
  • CSP-J历年真题(部分)解析与题解
    目录序言:[CSP-J2020]直播获奖前言:题目描述输入格式输出格式输入输出样例说明/提示样例1解释数据规模与约定提示65分思路及代码前言:思路:代码:85分代码及思路:前言:插入排序:思路:代码: AC思路及代码:前言:思路:   代码: [CSP-J2022]乘方前言:题目描......
  • C语言 | Leetcode C语言题解之第445题两数相加II
    题目:题解:structListNode*addTwoNumbers(structListNode*l1,structListNode*l2){intstack1[100];intstack2[100];inttop1=0;inttop2=0;intcarry=0;intsum=0;structListNode*temp=NULL;structListNode*he......
  • C语言 | Leetcode C语言题解之第443题压缩字符串
    题目:题解:voidswap(char*a,char*b){chart=*a;*a=*b,*b=t;}voidreverse(char*a,char*b){while(a<b){swap(a++,--b);}}intcompress(char*chars,intcharsSize){intwrite=0,left=0;for(intr......