题意分析
1)纸带中每一个格子有三个元素:编号、颜色、上面的数字;
2)三元组的(x,y,z)满足条件
a.x, y, z都是整数, x < y < z, y − x = z − y
b.colorx=colorz
c.满足上述条件的三元组的分数规定为(x+z)∗(numberx+numberz)。
3)求出纸带中,所有满足的三元组条件的分数和模10007的值
样例分析:
1)所有满足条件的三元组为: (1, 3, 5), (4, 5, 6)。
2)纸带的分数为(1 + 5) * (5 + 2) + (4 + 6)* (2 + 2) = 42 + 40 = 82。
考察知识点:
数学、前缀和
时间复杂度:
o(n)
思路分析
1)分析特殊三元组的 条件:根据条件1:y-x = z-y;通过等式的性质,我们可以变换为:
y-x=z-y
y+y=z+x
z+x=2y
分析得出:z+x必定为偶数,由此推出x和z的就行必须相等,所以特殊三元组成立的条件为:
1 z>x
2 z和x的奇偶性相同
3 z格和x格的颜色相同
所以:只要有两个数奇偶性相同,颜色相同,那他们必是会产生分数
2)分数计算公式:分数 = (x+z)*(num[x]+num[z]);对于一种颜色同奇偶性的,有如下推导公式:

3)根据推到公式就可以进行计算纸带的分数总和
细节及小技巧
1)结果可能太大需要边做边模10007;
2)使用前缀和预处理相同颜色,奇偶数相同的格子
3)不同平台下long long类型用的格式控制不一样:
WIN32 %I64d
Linux %lld
WIN64 %I64d %lld
C++ 代码
#include <iostream>
#ifdef WIN32
#define LL "%l64d"
#else
#define LL "%lld"
#endif
using namespace std;
int n,c;
const int M = 100007;
long long maxx = 0;
int num[100005],col[100005];
int sum[2][100005];
int d[2][100005];
int main(){
scanf("%d%d",&n,&c);
for (int i = 1; i <= n; i++){
scanf("%d",&num[i]);
num[i] %=M;
}
int n1 = 0,n2 = 0;
for (int i = 1; i <= n; i++){
scanf("%d",&col[i]);
sum[i%2][col[i]] +=num[i];
d[i%2][col[i]]++;
sum[i%2][col[i]] %=M;
}
for (int i = 1; i <= n; i++){
maxx +=1LL*i%M*((sum[i%2][col[i]]+(d[i%2][col[i]]-2)%M*num[i])%M);
maxx %=M;
}
printf(LL,maxx);
return 0;
}