前缀和求助!
查看原帖
前缀和求助!
327139
纯白楼主2021/10/16 11:15
#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+b)*(num(a)+(num(b) )
anum(a)+bnum(b)+anum(b)+bnum(a)a*num(a) + b*num(b) + a* num(b) + b * num(a)
然后我们就可以整理出以奇数和偶数作为分类的各项在前缀和,具体在注释
然后只有60分,wa 了1,3,4,5 请大佬指教orz

2021/10/16 11:15
加载中...