题目描述
n n n 个数构成的数列 a n a_n an ,问其中有多少个等差数列。 n ≤ 1 0 3 , v ≤ 2 × 1 0 4 n \le 10^3 ,v \leq2 \times 10^4 n≤103,v≤2×104
注意
- 等差数列的公差可以为负数。
- 只有一个数时也视为等差数列
输入格式
第一行一个正整数
n
n
n。
第二行 n n n 个非负整数 a [ i ] a[i] a[i] 。
输出格式
输出一个整数,表示美观的方案数模
998244353
998244353
998244353 的值。
输入输出样例
输入
8
13 14 6 20 27 34 34 41
输出 50
输入
100
90 1004 171 99 1835 108 81 117 141 126 135 144 81 153 193 81 962 162 1493 171 1780 864 297 180 532 1781 189 1059 198 333 1593 824 207 1877 216 270 225 1131 336 1875 362 234 81 288 1550 243 463 1755 252 406 261 270 279 288 1393 261 1263 297 135 333 872 234 881 180 198 81 225 306 180 90 315 81 81 198 252 81 297 1336 1140 1238 81 198 297 661 81 1372 469 1132 81 126 324 333 342 81 351 481 279 1770 1225 549
输出 11153
分析:
设数组 b[i][j]
其中i j
分别表示下标和方差,然后进行两重循环枚举(内层循环仍然枚举n
,而不是枚举方差,读者可以思考这是为什么)。内层结束之后用栈来统计答案,避免重复统计。
代码:
#include<stdio.h>
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
const int MAXn = 1e4 + 5;
const int MOD = 998244353;
int read(){
int w = 0, r = 0;char ch = getchar();
while(ch <'0' || ch > '9')w|=ch == '-', ch = getchar();
while(ch >= '0' && ch <= '9')r = (r<<1)+(r<<3)+(ch^48), ch = getchar();
return w ? ~r + 1 : r;
}
int n, a[MAXn], b[1005][40010];
int sta[MAXn], top;
bool vis[40010];
int main(){
n = read();
int ans = 0;
for(int i = 1; i <= n; i++)a[i] = read();
for(int i = 2; i <= n; i++){
for(int j = 1; j <= i - 1; j++){
int variance = a[i] - a[j];
if(variance < 0)variance += 40005;//处理负数情况
b[i][variance] += b[j][variance] + 1;//转移方程
b[i][variance] %= MOD;
vis[variance] = 1;
sta[++top] = variance;
}
do{//栈统计答案
int p = sta[top--];
if(vis[p]){
ans += b[i][p];
ans %= MOD;
vis[p] = false;
}
}while(top);
}
printf("%d", (ans + n)%MOD);
return 0;
}
后来我看到了别人的代码:
#include <bits/stdc++.h>
using namespace std;
const int MOD=998244353;
int a[1002],f[1002][40002],ans;
int main(){
int n;cin>>n;
for(int i=1;i<=n;++i) scanf("%d",a+i);
ans=n;
for(int i=2;i<=n;++i)
for(int j=1;j<i;++j){
int d=20000+a[i]-a[j];
f[i][d]++,ans++;
if(f[j][d])f[i][d]=(f[i][d]+f[j][d])%MOD,ans=(ans+f[j][d])%MOD;
}
cout<<ans%MOD;
}
直接统计了答案没有用栈,简洁美观。
我需要学习的地方还有很多啊,ヾ(◍°∇°◍)ノ゙加油!