题目描述:
解题过程:
最初以为是一个循环节问题,样例确实是循环的,多写几组就发现了。但是,其实是一个坑,根本不是什么循环节。于是我直接暴力做了一遍,过了一半数据:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
typedef long long ll;
int main(){
ll n,k,t;
ll a[maxn],pos=0,num=1,sum=0;
a[pos++]=num;
cin>>n>>k>>t;
for(int i=1;i<=(t-1)*n;i++){
num+=i;
if(num>=k){
num%=k;
}
a[pos++]=num;
}
for(int i=0;i<pos;i++){
if(i%n==0){
sum+=a[i];
}
}
cout<<sum<<endl;
return 0;
}
不难想到,数据量级太大时会出现栈溢出,超时等问题。于是,参考网上大佬的解法:我们不需要关心其他人报的什么数,只需要看栋栋报的数是多少。每个人报数字的大小都会比之前大一,也就是每次增加的值1,2,3,4,5,…n这样一个数列。对于栋栋的三次报数1,7,9是这样得来的,(1+(1+2+3))%k=7 ,(1+(1+2+3+4+5+6))%k=9或(7+(4+5+6))%k=9。规律就是栋栋报的数字就是他报的前一个数字加上一段等差数列的和。
题解:
#include<bits/stdc++.h>
using namespace std;
const int maxn=10005;
typedef long long ll;
int main(){
ll n,k,t;
ll sum=1,x=1,a=1;
cin>>n>>k>>t;
for(ll i=1;i<=(t-1);i++){
x=(x+(a+a-1+n)*n/2)%k;
sum+=x;
a+=n;
}
cout<<sum;
return 0;
}