【Luogu P2671】求和
题目大意:
定义一种特殊的三元组:\((x,y,z)\),其中 \(x,y,z\) 都代表纸带上格子的编号,而且要求满足以下两个条件:
-
\(x<y<z,y-x=z-y\quad(x,y,z\in\mathbb{Z})\)。
-
\(color_x=color_y\)。
最后求出所有三元组价值之和,每个三元组价值为 \((x+z)\times(number_x+number_z)\)。
正文:
方法 1:
暴力枚举 \(x,z\)。
for (int l = 1; l <= n; l++)
{
for (int r = l + 2; r <= n; r += 2)
{
if(b[l] == b[r])
{
ans += (a[l] + a[r]) % p * (l + r) % p;
}
}
}
方法 2:
由法1得到一个性质:\(x,z\) 要么都是奇数要么都是偶数,那么给每个格子奇偶分组,用前缀和维护就能 \(O(n)\) 解决问题。
for (int i = 1; i <= n; i++) scanf ("%d", &a[i]);
for (int i = 1; i <= n; i++)
{
scanf ("%d", &b[i]);
s[b[i]][i & 1]++;
sum[b[i]][i & 1] = (sum[b[i]][i & 1] + a[i]) % p;
}
for (int i = 1; i <= n; i++)
{
ans = (ans + i * ((s[b[i]][i & 1] - 2) % p * a[i] % p + sum[b[i]][i & 1]) % p) % p;
}
printf("%lld", ans);