题目描述
题解
容易发现中间的那一个点是没有用的,所以只需要考虑每一对颜色相同并且下标相加是偶数的点就行了。
下标相加是偶数!那么有一条非常显然的性质:只能是两个奇数相加或者两个偶数相加!
也就是说,颜色相同的、下标都为奇数/偶数的一坨点两两之间一定存在答案。
考虑假设一组点为x1,x2….xn,两两之间都存在答案,这个答案为
x1∗(v1∗(n−1)+v2+...+vn)+x2(v2∗(n−1)+v1+v3+...+vn)+...+xn(vn∗(n−1)+v1+...+vn−1)
。由最原始的式子展开就可以得到。
预处理出来每一组的总和以及元素个数就可以在
O(n)
的时间里计算出来。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 100005
#define Mod 10007
int n,m,ans;
int color[N],num[N],sum[N][2],tot[N][2];
int main()
{
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",&color[i]);
for (int i=1;i<=n;++i)
{
sum[color[i]][i&1]=(sum[color[i]][i&1]+num[i])%Mod;
tot[color[i]][i&1]++;
}
for (int i=1;i<=n;++i)
{
int now=((sum[color[i]][i&1]-num[i]+num[i]*(tot[color[i]][i&1]-1)%Mod)%Mod+Mod)%Mod;
ans=(ans+now*i%Mod)%Mod;
}
printf("%d\n",ans);
}
总结
①又是一道性质题。考虑性质要全面,不要光在一个角度思考。有时候最显然的性质也最容易被忽略。