首页 > 其他分享 >【XSY3988】安静(数学,根号分类讨论)

【XSY3988】安静(数学,根号分类讨论)

时间:2022-10-31 07:33:58浏览次数:43  
标签:安静 mathbb 32 times 120 leq 64 XSY3988 根号

题面

安静

题解

首先题目的条件可以看作是:如果当前时刻 \(X\) 模 \(T_i\) 为 \(j\),那么就会得到 \(f_i(j)\) 的贡献。构造一个答案时刻 \(X\),使得总贡献最大,求总贡献的最大值。

注意到 \(t\leq 120\),那么我们将 \(T_i\) 相同的归到一类:设 \(f(t,j)\) 表示当前时刻 \(X\) 模 \(t\) 为 \(j\) 时的总贡献,那么接下来整道题都与 \(n\) 无关了。

现在题目的要求变成了:如果当前时刻 \(X\) 模 \(t\) 为 \(j\),那么就会得到 \(f(t,j)\) 的贡献。构造一个答案时刻 \(X\),使得总贡献最大,求总贡献的最大值。


先来考虑一种最朴素的做法。

令集合 \(\mathbb{P}=\{2,3,5,7,\cdots,113\}\) 表示所有小于等于 \(120\) 的质数的集合,那么所有的 \(t\) 所包含的所有质因子都在集合 \(\mathbb{P}\) 内。

设 \(p\) 为集合 \(\mathbb{P}\) 内某一元素,定义 \(m_p=\left\lfloor\log _p 120\right\rfloor\),那么 \(m_p\) 就表示在所有的 \(t\) 的分解质因数中 \(p\) 的幂次最高能到多少。

对于任意一个 \(1\leq t\leq 120\),考虑 \(X\) 模 \(t\) 的余数是什么。

考虑一个数 \(M=\prod\limits_{p \in \mathbb{P}}p^{m_p}\),发现 \(M\) 始终是 \(t\) 的倍数,所以 \(X\equiv X-M\pmod t\),即 \(X\equiv X\bmod M\pmod t\)。

那么我们可以枚举 \(X\) 模 \(M\) 的余数 \(r\),那么 \(X\equiv r\pmod t\),那么我们就可以算此时的贡献了。

那么我们就能在把无限次数地枚举 \(X\) 找最大贡献转换成有限次数地枚举 \(r\) 找最大贡献了。

设 \(T=120\),那么此算法的时间复杂度为 \(O(MT)\),考虑继续优化。

下面用 \([a,b]\) 表示 \(a,b\) 的最小公倍数。

我们考虑将 \(f(2^{m_2},*)\) 合并到 \(f(2^{m_2-1},*)\),即 \(f(64,*)\) 合并到 \(f(32,*)\):

首先,如果 \(X\bmod 32=r\),那么肯定有 \(X \bmod 64=r\) 或 \(X\bmod 64=32+r\)。

假设当前 \(X\bmod 32=r\) 且 \(X\bmod 64=r\),但如果 \(X\bmod 64=32+r\) 的贡献会更大。

我们考虑一个数 \(M'=32\times \prod\limits_{p\in \mathbb{P},p\neq 2}p^{m_p}\),显然对于所有的 \(1\leq t\leq 120\),都有 \(M'\equiv 0\pmod{t}\),除了 \(t=64\) 时 \(M'\equiv 32\pmod{64}\)。

那么我们此时让 \(X\gets X+M'\),就能使得 \(X\) 模其他数的值不变,而 \(X\) 模 \(64\) 变成 \(32+r\) 了。

所以可以把 \(\max\big(f(64,r),f(64,32+r)\big)\) 的贡献合并到 \(f(32,r)\) 上。

同理可以把 \(f(81,*)\) 合并到 \(f(27,*)\) 上。

我们又考虑把 \(f(1\times 7^2,*),f(2\times 7^2,*)\) 合并到 \(f([1,2]\times 7,*)\) 上。

同理可以把 \(f(1\times 5^2,*),f(2\times 5^2,*),f(3\times 5^2,*),f(4\times 5^2,*)\) 合并到 \(f([1,2,3,4]\times 5,*)\) 上,

那么 \(2,3,5,7\) 的最高次分别降为 \(2^5,3^3,5,7\)。

(当然也可以把 \(2^5\) 和 \(3^3\) 按 \(5\)、\(7\) 的方法降下来,不过要保证最小公倍数乘上 \(p^k\) 要能被 \(M'\) 整除)

我们把 \(\mathbb{P}\) 分为两类 \(\mathbb{P}_1\) 和 \(\mathbb{P}_2\),其中 \(\mathbb{P}_1=\{2,3,5,7\}\) 表示所有小于等于 \(\sqrt{120}\) 的质数的集合, \(\mathbb{P}_2=\{11,13,\cdots,113\}\) 表示所有大于 \(\sqrt{120}\) 小于等于 \(120\) 的质数的集合。

设集合 \(\mathbb{T}_1\) 表示所有的整数 \(t\) 满足 \(1\leq t\leq 120\) 且 \(t\) 不含大于 \(\sqrt{120}\) 的质因子,集合 \(\mathbb{T}_2\) 表示所有的整数 \(t\) 满足 \(1\leq t\leq 120\) 且 \(t\) 包含大于 \(\sqrt{120}\) 的质因子。显然 \(\mathbb{T_1}\) 中的数的所有质因子只存在于 \(\mathbb{P}_1\) 内,而 \(\mathbb{T_2}\) 中的数的质因子可以同时存在 \(\mathbb{P}_1,\mathbb{P}_2\) 内,也可以只存在于 \(\mathbb{P}_2\) 内,但存在于 \(\mathbb{P}_2\) 内的质因子只能有一个,且其幂次一定为 \(1\)。

我们考虑分开讨论:先枚举 \(X\) 模 \(2^5\times 3^3\times 5\times 7=30240\) 的余数 \(r\),计算集合 \(\mathbb{T}_1\) 的答案,再和集合 \(\mathbb{T}_2\) 合并。

代码如下:

#include<bits/stdc++.h>

#define T 125

using namespace std;

inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^'0');
		ch=getchar();
	}
	return x*f;
}

const int P=30240;
const int p2[]={26,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113};

int n,ans,f[T][T],s[T];
bool vis[T];

void clear(int x)
{
	memset(f[x],0,sizeof(f[x]));
}

int main()
{
	n=read();
	for(int i=1;i<=n;i++)
	{
		int t=read();
		for(int j=0;j<t;j++)
			f[t][j]+=read();
	}
	for(int i=0;i<32;i++)
		f[32][i]+=max(f[64][i],f[64][i+32]);
	clear(64);
	for(int i=0;i<27;i++)
		f[27][i]+=max(f[81][i],max(f[81][i+27],f[81][i+54]));
	clear(81);
	for(int i=0;i<14;i++)
	{
		int maxn=0;
		for(int j=i;j<112;j+=14)
			maxn=max(maxn,f[49][j%49]+f[98][j]);
		f[14][i]+=maxn;
	}
	clear(49),clear(98);
	for(int i=0;i<60;i++)
	{
		int maxn=0;
		for(int j=i;j<360;j+=60)
			maxn=max(maxn,f[25][j%25]+f[50][j%50]+f[75][j%75]+f[100][j%100]);
		f[60][i]+=maxn;
	}
	clear(25),clear(50),clear(75),clear(100);
	for(int i=1;i<=p2[0];i++)
		for(int j=p2[i];j<=120;j+=p2[i]) vis[j]=1;
	for(int r=0;r<P;r++)
	{
		int sum=0;
		for(int i=1;i<=120;i++)
			if(!vis[i]) sum+=f[i][r%i];
		for(int i=1;i<=p2[0];i++)
		{
			memset(s,0,sizeof(s));
			int p=p2[i];
			for(int j=p;j<=120;j+=p)
			{
				int now=r%j;
				do
				{
					s[now%p]+=f[j][now];
					now=(now+P)%j;
				}while(now!=r%j);
			}
			int maxn=0;
			for(int j=0;j<p;j++)
				maxn=max(maxn,s[j]);
			sum+=maxn;
		}
		ans=max(ans,sum);
	}
	printf("%d\n",ans);
	return 0;
}
/*
3
2 0 1
3 1 2 0
4 1 0 2 0
*/
/*
3
6 1 3 5 2 7 4
10 3 7 2 2 5 1 8 9 4 6
15 4 5 8 7 8 8 5 4 5 2 7 5 5 4 7
*/

这篇题解很多地方讲得不是很清楚,需要自己手推。

标签:安静,mathbb,32,times,120,leq,64,XSY3988,根号
From: https://www.cnblogs.com/ez-lcw/p/16842956.html

相关文章

  • 【XSY2423】跳蚤(根号分治)
    题面题解神奇的分类讨论。首先注意到每次所有跳蚤都只会往右跳,也就是说只要某一只跳蚤跳出了\(\max(r_i)\)它就不会再有贡献了。(和火神的鱼类似)令\(R=\max(r_i)......
  • 根号分治简单笔记 | P3396 哈希冲突
    简要题意你需要维护一个长度为\(n\)的序列\(v\),支持:Axy求整个序列中,所有模\(x\)为\(y\)的下标的元素的值,即:\[\sum_{i=0}^{\lfloor(n-y)\divx\rfloor}v_{ix......
  • 三角形ABC中,AB=AC,AD=2,BD*CD=2倍根号3,求AC长度?
    2022年10月23日11点09分END......
  • Snowy Mountain (找规律来贪心+ 多源特殊bfs+根号n)
    题目大意:给定一棵 nn 个点的树,其中每个点可能是黑色或白色。一个点的高度定义为其距离最近黑色节点的距离。你初始在 ii 号节点上,势能为 00,可以做以下两种操作:......
  • 根号算法学习记录
    根号算法专题分块基础根号平衡对于两个不同方面的复杂度,直接做的话一个很小,一个很大,我们用根号使得两者复杂度同阶级以降低总复杂度。这个叫根号平衡。一个典型的应用......
  • 洛谷 P8572【暴力】【根号分治】
    根号分治。需要进行分类讨论:当\(n\lek\)的时候,可以进行暴力\(\#1\):暴力求出数组所有区间的最大值。(需要使用前缀和)否则,可以使用一个叫做“记忆化”的鬼玩意。如......
  • 【luogu CF1553F】Pairwise Modulo(树状数组)(根号分治)
    PairwiseModulo题目链接:luoguCF1553F题目大意给你一个序列,对于每个前缀,要你求两两互相取模的结果的和。思路考虑新加入一个数增加的答案。那就是加两个部分:\(\sum......
  • 基于systemgenerator的根号计算
    一、系统设计仿真结果以及硬件资源估计(用于复制到你的那个txt文件中去即可。)顶层框图: 整个系统的结构如下所示: 进入内部模块则有: 其主要由三大部分组成: 第一部分:输入信......
  • 2022牛客OI赛前集训营-提高组(第一场) 奇怪的函数 根号很好用
    奇怪的函数考虑暴力,每次查询\(O(n)\)扫所有操作,修改\(O(1)\)这启发我们平衡复杂度,考虑分块。观察题目性质,可以发现,经过若干次操作后得到的结果一定是一个关于\(x\)的分......
  • 【luogu P4218】珠宝商(SAM)(点分治)(根号分治)
    珠宝商题目链接:luoguP4218题目大意给你一棵树,每个点有一个字符。再给你一个字符串s。然后问你树上的所有简单的路径在s上的出现次数的和。思路一个比较神奇的题......