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

题面

安静

题解

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

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

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


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

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

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

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

考虑一个数 M = ∏ p ∈ P p m p M=\prod\limits_{p \in \mathbb{P}}p^{m_p} M=pPpmp,发现 M M M 始终是 t t t 的倍数,所以 X ≡ X − M ( m o d t ) X\equiv X-M\pmod t XXM(modt),即 X ≡ X   m o d   M ( m o d t ) X\equiv X\bmod M\pmod t XXmodM(modt)

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

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

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

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

我们考虑将 f ( 2 m 2 , ∗ ) f(2^{m_2},*) f(2m2,) 合并到 f ( 2 m 2 − 1 , ∗ ) f(2^{m_2-1},*) f(2m21,),即 f ( 64 , ∗ ) f(64,*) f(64,) 合并到 f ( 32 , ∗ ) f(32,*) f(32,)

首先,如果 X   m o d   32 = r X\bmod 32=r Xmod32=r,那么肯定有 X   m o d   64 = r X \bmod 64=r Xmod64=r X   m o d   64 = 32 + r X\bmod 64=32+r Xmod64=32+r

假设当前 X   m o d   32 = r X\bmod 32=r Xmod32=r X   m o d   64 = r X\bmod 64=r Xmod64=r,但如果 X   m o d   64 = 32 + r X\bmod 64=32+r Xmod64=32+r 的贡献会更大。

我们考虑一个数 M ′ = 32 × ∏ p ∈ P , p ≠ 2 p m p M'=32\times \prod\limits_{p\in \mathbb{P},p\neq 2}p^{m_p} M=32×pP,p=2pmp,显然对于所有的 1 ≤ t ≤ 120 1\leq t\leq 120 1t120,都有 M ′ ≡ 0 ( m o d t ) M'\equiv 0\pmod{t} M0(modt),除了 t = 64 t=64 t=64 M ′ ≡ 32 ( m o d 64 ) M'\equiv 32\pmod{64} M32(mod64)

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

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

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

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

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

那么 2 , 3 , 5 , 7 2,3,5,7 2,3,5,7 的最高次分别降为 2 5 , 3 3 , 5 , 7 2^5,3^3,5,7 25,33,5,7

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

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

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

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

代码如下:

#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
*/

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值