1. 程式人生 > 實用技巧 >【Luogu P2671】求和

【Luogu P2671】求和

題目大意:

定義一種特殊的三元組:\((x,y,z)\),其中 \(x,y,z\) 都代表紙帶上格子的編號,而且要求滿足以下兩個條件:

  1. \(x<y<z,y-x=z-y\quad(x,y,z\in\mathbb{Z})\)

  2. \(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);