很明显,这道题的答案只会由倒数第 n 行的后 ⌈2k+1⌉ 个数和第 n−1 行的后 ⌊2k⌋ 个数组成。也就是答案其实是两个等差数列的和。
下面是我的代码:
#include<bits/stdc++.h>
#define int unsigned long long
const int mod=1000000007;
using namespace std;
int T;
int n,k;
long double ans;
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^48),ch=getchar();
return x*f;
}
inline void write(int x){
if(x<0) x=~x+1,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
void solve(){
n=read();
k=read();
ans=0.00;
if(k%2==1){
int a=(k+1)/2;
int b=k/2;
int lasta=n*(n+1)/2;
int lastb=(n-1)*n/2;
int starta=lasta-a+1;
int startb=lastb-b+1;
//cout<<(starta+lasta)%mod*a/2<<" "<<(startb+lastb)%mod*b/2<<endl;
ans=(starta+lasta)*a/2+(startb+lastb)*b/2;
}
else{
int a=k/2;
int b=k/2;
int lasta=n*(n+1)/2;
int lastb=(n-1)*n/2;
int starta=lasta-a+1;
int startb=lastb-b+1;
ans=(starta+lasta)*a/2+(startb+lastb)*b/2;
}
cout<<(int)ans%mod<<endl;
//write((int)ans%mod);
//putchar('\n');
}
signed main(){
T=read();
while(T--) solve();
}
由于一些奇怪的原因,这样子算只能拿到 90 分。不过显然会炸 long long。因为 max{lasta} 约为 1018。
于是在中途取了个模:https://www.luogu.com.cn/record/56114171
然后只能 AC 第一个Subtask。
赛后有同学跟我讲可以用 long double 卡过去,但是我没有成功(
所以我想知道:我这个思路能否卡过去?或者本来就是要卡掉这个做法?