NOI Online #1 提高组 T3 最小环

原题链接

简洁题意:

一个环上有数字,给定一个距离 k k k,构造一个序列使 ∑ i = 1 n ( a i × a i + k ) \sum^{n}_{i=1}(a_i\times a_{i+k}) i=1n(ai×ai+k)最大。这里指的是环上加减。

分析:

这个题很容易想到一个策略,把两个大的相乘很明显更划算。于是能想到由 1 1 1开始 b f s bfs bfs,扩展出来左右两边的数,从大到小放数字。但这样很容易出现一个问题:有些永远不可能搜到!比如题目中的样例, k = 3 k=3 k=3的情况就有一半会搜不到。有一种解决方法:标记每一位,像 t a r j a n tarjan tarjan一样,每一个点看看有没有标记,没有标记就搜。这种方法时间复杂度是 Θ ( n ) \Theta(n) Θ(n)的,可行,但是我没有试过。这是考试的时候想的,但是时间不够,就没写了。下面说一个代码简洁的方法:
针对上面的问题不难发现,这样分出来每一次搜索可以划分为一组。那么一组有多少个呢?就是 n ÷ g c d ( n , k ) n\div gcd(n,k) n÷gcd(n,k)个。这个我不会证明,纯粹是一个一个试出来规律的。要是有巨佬会证明的在评论区说一下,我会加上并特别鸣谢的。于是,分成了很多组就好办了。每一组互不干扰,再根据前面 b f s bfs bfs的方法,发现一组中分到的数字是连续的。不难发现,在一组中除了最大和次大、最小和次小相乘,这一组里面都是 a i + 2 × a i a_{i+2}\times a_{i} ai+2×ai的。注意,为了方便放大的数,这里的 a a a是已经从大到小排序的。于是,我们也可以每次 i i i加上一组的个数,这样就相当于把 a a a的一部分分给前一组了。时间复杂度也是 Θ ( n ) \Theta(n) Θ(n)的。
针对上面两种方法,时间复杂度仍然不够用,因为会有很多个 k k k要求。但是发现, k k k最大小于 n ÷ 2 n\div2 n÷2,也就是 1 0 5 10^5 105 k k k要求,但是却会有 1 0 5 × 2 10^5\times2 105×2 k k k。如果每个分别求,会 T L E TLE TLE几个点。但是,求的个数比种数多很多,肯定有很多重复。所以可以用一个 f f f数组存每个 k k k的答案,遇到重复的直接输出。但是这样时间仍然很紧,不难发现只要分的组是一样的答案就是一样的。我们又能少输出很多个 k k k了,注意这样优化第一个方法就也要求一个一组的个数。
总时间复杂度 Θ ( k n ) \Theta(kn) Θ(kn)

代码:

#include<bits/stdc++.h>
using namespace std;
const int NN=2e5+4;
long long a[NN],f[NN];
int gcd(int a,int b)
{
    
    
	return !b?a:gcd(b,a%b);
}
int main()
{
    
    
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	sort(a+1,a+1+n);
	while(m--)
	{
    
    
		int k;
		scanf("%d",&k);
		long long ans=0;
		if(k==0||n==1)
		{
    
    
			if(f[0])
			{
    
    
				printf("%lld\n",f[0]);
				continue;
			}
			for(int i=1;i<=n;i++)
				ans+=a[i]*a[i];
			f[0]=ans;
			printf("%lld\n",ans);
			continue;
		}
		int team=n/gcd(n,k);
		if(f[team])
		{
    
    
			printf("%lld\n",f[team]);
			continue;
		}
		for(int i=1;i<=n;i+=team)
		{
    
    
			for(int j=0;j<team-2;j++)
				ans+=a[i+j]*a[i+j+2];
			ans+=(a[i]*a[i+1]+a[i+team-1]*a[i+team-2]);
		}
		f[team]=ans;
		printf("%lld\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44043668/article/details/108808511