RPG的跑腿任务
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 25 Accepted Submission(s) : 8
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Luke最近沉迷一款RPG游戏,游戏中角色可以通过完成跑腿任务获取奖励。
所谓跑腿任务就是在某个NPC(非玩家角色)领取任务,然后移动到指定NPC处完成任务即可,此过程中玩家角色移动的最短距离即是本次任务的行程。
游戏的地图可以看作一条数轴,从左至右第i位NPC与第i+1位NPC的距离为ai。任意两位NPC之间都存在一个跑腿任务(从靠左的NPC处领取,在另一NPC处完成),问所有任务的行程之和(不考虑任务之外的角色移动)。
为了避免溢出long long,请将结果对10^9+7取余!
因为输入数据非常大,为了降低输入数据导致的开销,这里使用随机数构造输入数据。
这里有一份C++版的读入模板
读入模板
Input
第一行为正整数t表示测试组数。
随后为t组输入,每组测试中,第一行为NPC数目n以及两个随机数种子k1 k2。gen()函数会帮助你们完成n k1 k2的读入和间隔ai的构造。
t<=10
1<=n<=10^6
0<=ai<=10^6
Output
每组测试输出一行表示所有任务行程之和,再次强调为了避免溢出long long,请将结果对10^9+7取余。
Sample Input
1 3 12345 54321
Sample Output
1992030 注:构造出来的间隔数组a为582786,413229
解析:
求和 a[i]*count(a[i])%mod
排列组合次数有: count(a[i]) = (k+1)*(n-k-1)
ac:
#include <iostream>
#include <cstdio>
#define ll long long
#define mod 1000000007
using namespace std;
const int N=1e6+5;
int n;
long long a[N];
unsigned long long k1,k2;
unsigned long long xorShift128Plus()
{
unsigned long long k3=k1,k4=k2;
k1=k4;
k3^=k3<<23;
k2=k3^k4^(k3>>27)^(k4>>26);
return (k2+k4)%999999+1;
}
void gen()
{
scanf("%d%llu%llu",&n,&k1,&k2);
for(int i=0; i<n-1; i++)
a[i]=xorShift128Plus();
}
ll count(ll n,ll k)
{
return ((k+1)*(n-k-1))%mod;
}
int main()
{
int t;
scanf("%d",&t);//读入样例数
while(t--)
{
gen();
ll sum=0;
for(int i=0;i<n-1;i++)
{
sum+=(a[i]*count(n,i))%mod;
sum=sum%mod;
}
printf("%lld\n",sum);
}
return 0;
}