LightOJ - 1328 A Gift from the Setter (数学)

本文探讨了一个由设定者提供的算法,用于解决序列差值和的问题。通过给出序列生成公式,要求读者实现算法并优化代码以避免超时错误。文章详细介绍了输入输出规范,并提供了样例输入输出以辅助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LightOJ - 1328
Time Limit:                                                        2000MS                       Memory Limit: 32768KB64bit IO Format:                            %lld & %llu                       

SubmitStatus

Description

Problem setting is somewhat of a cruel task of throwing something at the contestants and having them scratch their head to derive a solution. In this problem, the setter is a bit kind and has decided to gift the contestants an algorithm which they should code and submit. The C/C++ equivalent code of the algorithm is given below:

longlongGetDiffSum(inta[],intn)
{
  
longlongsum=0;
  
inti,j;
  
for(i=0;i<n;i++)
      
for(j=i+1;j<n;j++)
            sum
+=abs(a[i]-a[j]);// abs means absolute value
  
returnsum;
}

The values of array a[] are generated by the following recurrence relation:

a[i] = (K * a[i-1] + C) % 1000007 for i > 0

where K, C and a[0] are predefined values. In this problem, given the values of K, C, n and a[0], you have find the result of the function

"long long GetDiffSum( int a[], int n )"

But the setter soon realizes that the straight forward implementation of the code is not efficient enough and may return the famous "TLE" and that's why he asks you to optimize the code.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case contains four integers K, C, n and a[0]. You can assume that (1 ≤ K, C, a[0] ≤ 104) and (2 ≤ n ≤ 105).

Output

For each case, print the case number and the value returned by the function as stated above.

Sample Input

2

1 1 2 1

10 10 10 5

Sample Output

Case 1: 1

Case 2: 7136758

Hint

Source

Problem Setter: Shamim Hafiz
Special Thanks: Jane Alam Jan, Sohel Hafiz
//题意:先告诉你计算a[i]的公式:a[i]=(k*a[i-1]+c)%1000007;
输入k,c,n,a[0],让你先求出有n个值的序列a[i],然后根据题中给出的计算sum的公式,计算出sum。
//思路:
很简单的一个题,求出来a[i]后,将它们从小到大排序(消除掉取绝对值),因为n是100000,所以两重for肯定会超时,所以就用一个前缀和数组sum记录,根据sum数组进行操作,一重for就行了。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define ll long long
#define N 100010
#define M 1000007
using namespace std;
ll a[N];
ll sum[N];
int main()
{
	int t,T=1;
	int k,c,n,m;
	int i,j;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%d%d",&k,&c,&n,&m);
		a[0]=m;
		for(i=1;i<n;i++)
			a[i]=(k*a[i-1]+c)%M;
		sort(a,a+n);
		for(i=0;i<n;i++)
			sum[i]=sum[i-1]+a[i];
		ll num=0;
		for(i=0;i<n;i++)
		{
			num+=sum[n-1]-sum[i-1]-a[i]*(n-i);
		}
		printf("Case %d: %lld\n",T++,num);
	}
	return 0;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值