求和(sum) \operatorname{求和(sum)} 求和(sum)
题目链接: SSL比赛 1491 \operatorname{SSL比赛\ 1491} SSL比赛 1491 / luogu P2671 \operatorname{luogu\ P2671} luogu P2671
题目
一条狭长的纸带被均匀划分出了
n
n
n 个格子,格子编号从
1
1
1 到
n
n
n 。每个格子上都染了一种颜色
c
o
l
o
r
i
color_i
colori (用
[
1
,
m
]
[1,m]
[1,m] 当中的一个整数表示),并且写了一个数字
n
u
m
b
e
r
i
number_i
numberi 。
定义一种特殊的三元组:
(
x
,
y
,
z
)
(x,y,z)
(x,y,z) ,其中
x
x
x ,
y
y
y ,
z
z
z 都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:
- x , y , z x,y,z x,y,z 都是整数, x < y < z , y − x = z − y x<y<z,\ \ y−x=z−y x<y<z, y−x=z−y
- c o l o r x = c o l o r z color_x=color_z colorx=colorz
满足上述条件的三元组的分数规定为 ( x + z ) ∗ ( n u m b e r x + n u m b e r z ) (x + z) ∗ (number_x + number_z) (x+z)∗(numberx+numberz) 。整个纸带的分数规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以 10 , 007 10,007 10,007 所得的余数即可。
输入
第一行是用一个空格隔开的两个正整数 n n n 和 m m m , n n n 代表纸带上格子的个数, m m m 代表纸带上颜色的种类数。
第二行有 n n n 个用空格隔开的正整数,第 i i i 个数字 n u m b e r i number_i numberi 代表纸带上编号为 i i i 的格子上面写的数字。
第三行有 n n n 个用空格隔开的正整数,第 i i i 个数字 c o l o r i color_i colori 代表纸带上编号为 i i i 的格子染的颜色。
输出
共一行,一个整数,表示所求的纸带分数除以 10 , 007 10,007 10,007 所得的余数。
样例输入1
6 2
5 5 3 2 2 2
2 2 1 1 2 1
样例输出1
82
样例解释1
纸带如题目描述中的图所示。
所有满足条件的三元组为:
(
1
,
3
,
5
)
,
(
4
,
5
,
6
)
(1, 3, 5), \ \ (4, 5, 6)
(1,3,5), (4,5,6) 。
所以纸带的分数为
(
1
+
5
)
∗
(
5
+
2
)
+
(
4
+
6
)
∗
(
2
+
2
)
=
42
+
40
=
82
(1 + 5) ∗ (5 + 2) + (4 + 6) ∗ (2 + 2) = 42 + 40 = 82
(1+5)∗(5+2)+(4+6)∗(2+2)=42+40=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
1 组至第
2
2
2 组数据,
1
≤
n
≤
100
,
1
≤
m
≤
5
1 ≤ n ≤ 100, 1 ≤ m ≤ 5
1≤n≤100,1≤m≤5 ;
对于第
3
3
3 组至第
4
4
4 组数据,
1
≤
n
≤
3000
,
1
≤
m
≤
100
1 ≤ n ≤ 3000, 1 ≤ m ≤ 100
1≤n≤3000,1≤m≤100 ;
对于第
5
5
5 组至第
6
6
6 组数据,
1
≤
n
≤
100000
,
1
≤
m
≤
100000
1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000
1≤n≤100000,1≤m≤100000 ,且不存在出现次数超过
20
20
20 的颜色;
对于全部
10
10
10 组数据,
1
≤
n
≤
100000
,
1
≤
m
≤
100000
,
1
≤
c
o
l
o
r
i
≤
m
,
1
≤
n
u
m
b
e
r
i
≤
100000
1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, 1 ≤ color_i ≤ m, 1 ≤ number_i ≤ 100000
1≤n≤100000,1≤m≤100000,1≤colori≤m,1≤numberi≤100000 。
思路
这道题是一个数学题。
我们可以发现,奇数的跟偶数的没有关系,就分成奇数跟偶数,但算的过程都是一样的。
那这个颜色的东西只会跟它奇偶性相同且颜色相同的东西有关系。
那同一组有关系的东西把它们记成
a
i
a_i
ai ,格子的数字就是
n
u
m
i
num_i
numi ,那答案就是:
(
a
[
1
]
+
a
[
2
]
)
∗
(
n
u
m
[
1
]
+
n
u
m
[
2
]
)
+
(
a
[
1
]
+
a
[
3
]
)
∗
(
n
u
m
[
1
]
+
n
u
m
[
3
]
)
+
…
…
+
(
a
[
1
]
+
a
[
k
]
)
∗
(
n
u
m
[
1
]
+
n
u
m
[
k
]
)
(a[1]+a[2])*(num[1]+num[2])+(a[1]+a[3])*(num[1]+num[3])+……+(a[1]+a[k])*(num[1]+num[k])
(a[1]+a[2])∗(num[1]+num[2])+(a[1]+a[3])∗(num[1]+num[3])+……+(a[1]+a[k])∗(num[1]+num[k])
+
(
a
[
2
]
+
a
[
3
]
)
∗
(
n
u
m
[
2
]
+
n
u
m
[
3
]
)
+
(
a
[
2
]
+
a
[
4
]
)
∗
(
n
u
m
[
2
]
+
n
u
m
[
4
]
)
+
…
…
+
(
a
[
2
]
+
a
[
k
]
)
∗
(
n
u
m
[
2
]
+
n
u
m
[
k
]
)
+(a[2]+a[3])*(num[2]+num[3])+(a[2]+a[4])*(num[2]+num[4])+……+(a[2]+a[k])*(num[2]+num[k])
+(a[2]+a[3])∗(num[2]+num[3])+(a[2]+a[4])∗(num[2]+num[4])+……+(a[2]+a[k])∗(num[2]+num[k])
+
…
…
+……
+……
+
(
a
[
k
−
1
]
+
a
[
k
]
)
∗
(
n
u
m
[
k
−
1
]
+
n
u
m
[
k
]
)
+(a[k-1]+a[k])*(num[k-1]+num[k])
+(a[k−1]+a[k])∗(num[k−1]+num[k])
接着,就开始了我们痛苦的化简公式:
前面的式子
=
=
=
a
[
1
]
∗
[
(
n
u
m
[
1
]
+
n
u
m
[
2
]
)
+
(
n
u
m
[
1
]
+
n
u
m
[
3
]
)
+
…
…
+
(
n
u
m
[
1
]
+
n
u
m
[
k
]
)
]
a[1]*[(num[1] + num[2]) + (num[1] + num[3]) + …… + (num[1] + num[k])]
a[1]∗[(num[1]+num[2])+(num[1]+num[3])+……+(num[1]+num[k])]
+
a
[
2
]
∗
[
(
n
u
m
[
2
]
+
n
u
m
[
1
]
)
+
(
n
u
m
[
2
]
+
n
u
m
[
3
]
)
+
…
…
+
(
n
u
m
[
2
]
+
n
u
m
[
k
]
)
]
+a[2]*[(num[2] + num[1]) + (num[2] + num[3]) + …… + (num[2] + num[k])]
+a[2]∗[(num[2]+num[1])+(num[2]+num[3])+……+(num[2]+num[k])]
+
…
…
+……
+……
+
a
[
k
]
∗
[
(
n
u
m
[
k
]
+
n
u
m
[
1
]
)
+
(
n
u
m
[
k
]
+
n
u
m
[
2
]
)
+
…
…
+
(
n
u
m
[
k
]
+
n
u
m
[
k
−
1
]
)
]
+a[k]*[(num[k] + num[1]) + (num[k] + num[2]) + …… + (num[k] + num[k-1])]
+a[k]∗[(num[k]+num[1])+(num[k]+num[2])+……+(num[k]+num[k−1])]
=
=
=
a
[
1
]
∗
[
n
u
m
[
1
]
∗
(
n
−
1
)
+
(
n
u
m
[
2
]
+
n
u
m
[
3
]
+
…
…
+
n
u
m
[
k
]
)
]
a[1]*[num[1]*(n-1)+(num[2]+num[3]+……+num[k])]
a[1]∗[num[1]∗(n−1)+(num[2]+num[3]+……+num[k])]
+
a
[
2
]
∗
[
n
u
m
[
2
]
∗
(
n
−
1
)
+
(
n
u
m
[
1
]
+
n
u
m
[
3
]
+
…
…
+
n
u
m
[
k
]
)
]
+a[2]*[num[2]*(n-1)+(num[1]+num[3]+……+num[k])]
+a[2]∗[num[2]∗(n−1)+(num[1]+num[3]+……+num[k])]
+
…
…
+……
+……
+
a
[
k
]
∗
[
n
u
m
[
k
]
∗
(
n
−
1
)
+
(
n
u
m
[
1
]
+
n
u
m
[
2
]
+
…
…
+
n
u
m
[
k
−
1
]
)
]
+a[k]*[num[k]*(n-1)+(num[1]+num[2]+……+num[k-1])]
+a[k]∗[num[k]∗(n−1)+(num[1]+num[2]+……+num[k−1])]
=
=
=
a
[
1
]
∗
[
n
u
m
[
1
]
∗
(
n
−
2
)
+
∑
n
u
m
[
i
]
a[1]*[num[1]*(n-2)+\sum num[i]
a[1]∗[num[1]∗(n−2)+∑num[i]
+
a
[
2
]
∗
[
n
u
m
[
2
]
∗
(
n
−
2
)
+
∑
n
u
m
[
i
]
+a[2]*[num[2]*(n-2)+\sum num[i]
+a[2]∗[num[2]∗(n−2)+∑num[i]
+
…
…
+……
+……
+
a
[
k
]
∗
[
n
u
m
[
k
]
∗
(
n
−
2
)
+
∑
n
u
m
[
i
]
+a[k]*[num[k]*(n-2)+\sum num[i]
+a[k]∗[num[k]∗(n−2)+∑num[i]
= ∑ ( a [ i ] ∗ n u m [ i ] ) ∗ ( n − 2 ) + ∑ a [ i ] ∗ ∑ n u m [ i ] =\sum (a[i]*num[i])\ \ *(n-2)+\sum a[i]*\sum num[i] =∑(a[i]∗num[i]) ∗(n−2)+∑a[i]∗∑num[i]
那我们就预处理
n
n
n 和
n
u
m
[
i
]
num[i]
num[i] ,
a
[
i
]
a[i]
a[i] 的话就枚举
i
i
i ,那其实
a
[
i
]
a[i]
a[i] 就是
i
i
i 。
那这道题就做出来了。
要用 l o n g l o n g long\ long long long
代码
#include<cstdio>
#define mo 10007
#define ll long long
using namespace std;
ll n, m, a[100001], b[100001], getn[2][100001], num[2][100001], ans;
int main() {
scanf("%lld %lld", &n, &m);//读入
for (ll i = 1; i <= n; i++) scanf("%lld", &a[i]);//读入
for (ll i = 1; i <= n; i++) {
scanf("%lld", &b[i]);//读入
getn[i & 1][b[i]] = getn[i & 1][b[i]] + 1;//求出数量
num[i & 1][b[i]] = (num[i & 1][b[i]] + a[i]) % mo;//求出和
}
for (ll i = 1; i <= n; i++) {
ans = (ans + ((getn[i & 1][b[i]] - 2) * i * a[i]) % mo + (i * num[i & 1][b[i]]) % mo) % mo;//按公式算
}
printf("%lld", ans);//输出
return 0;
}