#include <cstdio>
#include <algorithm>
#include <iostream>
#define ll long long
using namespace std;
const ll maxn=2e6;
const ll mod = 10007;
template <typename T>
inline void read(T &x)
{
x = 0;
T f=1;
char c=getchar();
for (;!isdigit(c);c=getchar())
{
if (c=='-')
f=-1;
}
for (;isdigit(c);c=getchar())
{
x = (x<<3) + (x<<1) + (c - '0');
}
x *= f;
}
struct node {
ll col, num, sor;
bool operator < (const node b)const{
return this->col < b.col;
}
}e[maxn];
ll n, m;
ll s, t;
ll cnt;
// odd 奇数,fodd偶数
ll odd[maxn],fodd[maxn]; //num
ll odds[maxn],fodds[maxn];//序号,即题目中x,z
ll oddx[maxn],foddx[maxn];//乘积
ll oddn,foddn;//奇偶数个数
ll ans;
ll lodd,flodd;
int main ()
{
//freopen("p2671_1.in","r",stdin);
cin >> n >> m;
for (int i=1; i<=n; i++)
e[i].sor=i;
for (int i=1; i<=n; i++)
cin >> e[i].num;
for (int i=1; i<=n; i++)
cin >> e[i].col;
sort(e+1, e+1+n);
/*for (int i=1; i<=n; i++)
cout << e[i].col << " " << i <<" ";*/
for (int i=1; i<=n; i++)
{
s = i;
if (i==1 && e[1].col == e[2].col)
{
odd[1] = e[1].num;
oddx[1] = e[1].num * e[1].sor;
odds[1] = e[1].sor;
lodd = 1;
oddn++;
i++;
}
--i;
do
{
++i;
if (e[i].sor%2)
{
odds[i] = odds[lodd] + e[i].sor;
odd[i]=odd[lodd] + e[i].num;
oddx[i]=oddx[lodd] + e[i].sor*e[i].num;
lodd=i;
oddn++;
}
else {
fodds[i] = fodds[flodd] + e[i].sor;
fodd[i] = fodd[flodd] + e[i].num;
foddx[i]=foddx[flodd] + e[i].sor*e[i].num;
foddn++;
flodd=i;
}
}while (e[i].col == e[i+1].col);
t=i;
for (int j=s; j<t; j++)
{
if (e[j].sor%2)
{
ans += e[j].num*e[j].sor*(--oddn);
ans += (oddx[lodd] - oddx[j]);
ans += e[j].sor*(odd[lodd] - odd[j]) ;
ans += e[j].num * (odds[lodd] - odds[j]);
ans %= mod;
}
else {
ans += e[j].num*e[j].sor*(--foddn) ;
ans += (foddx[flodd] - foddx[j]) ;
ans += e[j].sor*(fodd[flodd] - fodd[j]);
ans += e[j].num * (fodds[flodd] - fodds[j]) ;
ans %=mod;
}
}
oddn = foddn =0;
}
printf ("%lld",ans%mod);
return 0;
}
代码如上
大概思路是
(a+b)∗(num(a)+(num(b))
a∗num(a)+b∗num(b)+a∗num(b)+b∗num(a)
然后我们就可以整理出以奇数和偶数作为分类的各项在前缀和,具体在注释
然后只有60分,wa 了1,3,4,5
请大佬指教orz