1. 程式人生 > 其它 >洛谷 P2671 [NOIP2015 普及組] 求和

洛谷 P2671 [NOIP2015 普及組] 求和

技術標籤:xxx

題目描述

一條狹長的紙帶被均勻劃分出了nn個格子,格子編號從11到nn。每個格子上都染了一種顏色color_icolor_i用[1,m][1,m]當中的一個整數表示),並且寫了一個數字number_inumber_i。
在這裡插入圖片描述

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

xyzxyz是整數,x<y<z,y-x=z-yx<y<z,y−x=z−y

colorx=colorzcolorx=colorz

滿足上述條件的三元組的分數規定為(x+z) \times (number_x+number_z)(x+z)×(number_x+number_z)。整個紙帶的分數規定為所有滿足條件的三元組的分數的和。這個分數可能會很大,你只要輸出整個紙帶的分數除以10,00710,007所得的餘數即可。

輸入格式

第一行是用一個空格隔開的兩個正整數nn和m,nm,n表紙帶上格子的個數,mm表紙帶上顏色的種類數。

第二行有nn用空格隔開的正整數,第ii數字numbernumber表紙帶上編號為ii格子上面寫的數字。

第三行有nn用空格隔開的正整數,第ii數字colorcolor表紙帶上編號為ii格子染的顏色。

輸出格式

一個整數,表示所求的紙帶分數除以1000710007所得的餘數。

輸入輸出樣例
輸入 #1 複製
6 2
5 5 3 2 2 2
2 2 1 1 2 1
輸出 #1 複製
82
輸入 #2 複製
15 4
5 10 8 2 2 2 9 9 7 7 5 6 4 2 4
2 2 3 3 4 3 3 2 4 4 4 4 1 1 1

輸出 #2 複製
1388

說明/提示

【輸入輸出樣例 1 說明】

紙帶如題目描述中的圖所示。

所有滿足條件的三元組為: (1, 3, 5), (4, 5, 6)(1,3,5),(4,5,6)。

所以紙帶的分數為(1 + 5) \times (5 + 2) + (4 + 6) \times (2 + 2) = 42 + 40 = 82(1+5)×(5+2)+(4+6)×(2+2)=42+40=82。

對於第 11 組至第 22 組資料, 1 ≤ n ≤ 100, 1 ≤ m ≤ 51≤n≤100,1≤m≤5;

對於第 33 組至第 44 組資料, 1 ≤ n ≤ 3000, 1 ≤ m ≤ 1001≤n≤3000,1≤m≤100;

對於第 55 組至第 6 6組資料, 1 ≤ n ≤ 100000, 1 ≤ m ≤ 1000001≤n≤100000,1≤m≤100000,且不存在出現次數超過 20 20的顏色;

對 於 全 部 1010 組 數 據 , 1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, 1 ≤ color_i ≤ m,1≤number_i≤1000001≤n≤100000,1≤m≤100000,1≤color_i≤m,1≤number_i≤100000

分析:

由三元組(x,y,z)(y-x=z-y) 可以發現x和z一定同為奇數或者同為偶數,因為只有這樣y才存在,所以可以將紙帶的編號根據奇偶分開。
假如 a b c 是符合要求的一組相同顏色,且編號都是奇數或都是偶數的格子(a1,b1,c1是數字)。
ans=(a+b) * (a1+b1) + (a+c) * (a1+c1) + (b+c) * (b1+c1)
ans=2aa1+a(b1+c1)+2bb1+a(a1+c1)+2cc1+a(a1+b1)
所以求每個顏色的奇數和偶數的個數以及數字之和就可以計算出答案。

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int N = 1e5+10;
const int mod = 10007;
ll num[N],c[N],d[2][N],co[2][N],r[2][N];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&num[i]);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&c[i]);	 
		d[i%2][c[i]]=(d[i%2][c[i]]+1)%mod;
		co[i%2][c[i]]=(co[i%2][c[i]]+num[i]%mod)%mod;
	}
	ll ans=0;
	for(int i=1;i<=n;i++)
	{
		ans=(ans+((d[i%2][c[i]]-1+mod)%mod*(i%mod)*(num[i]%mod))%mod)%mod;
		ans=(ans+(i%mod*((co[i%2][c[i]]-(num[i]%mod)+mod)%mod))%mod)%mod;
	}
	printf("%lld",ans);
	return 0;
 }