[BZOJ3378] [Usaco2004 Open]MooFest 狂欢节(树状数组)

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ3378] [Usaco2004 Open]MooFest 狂欢节(树状数组)相关的知识,希望对你有一定的参考价值。

传送门

 

开2个树状数组

一个存的是下标,一个存的是数量

细节。。。看标称吧,懒得说了,好气啊

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 20001 
#define LL long long
#define max(x, y) ((x) > (y) ? (x) : (y))

int n, m;
LL ans, sum, c[N], d[N];

struct node
{
	LL x, v;
}p[N];

inline int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;
	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
	return x * f;
}

inline bool cmp(node x, node y)
{
	return x.v < y.v;
}

inline LL query1(int x)
{
	LL ret = 0;
	for(; x; x -= x & -x) ret += d[x];
	return ret;
}

inline LL query2(int x)
{
	LL ret = 0;
	for(; x; x -= x & -x) ret += c[x];
	return ret;
}

inline void add1(int x, LL y)
{
	for(; x <= m; x += x & -x) d[x] += y;
}

inline void add2(int x, LL y)
{
	for(; x <= m; x += x & -x) c[x] += y;
}

int main()
{
	int i;
	n = read();
	for(i = 1; i <= n; i++)
	{
		p[i].v = read();
		p[i].x = read();
		m = max(m, p[i].x);
	}
	std::sort(p + 1, p + n + 1, cmp);
	for(i = 1; i <= n; i++)
	{
		ans += (p[i].x * query2(p[i].x) - query1(p[i].x)) * p[i].v;
		ans += (sum - query1(p[i].x) - p[i].x * (i - query2(p[i].x) - 1)) * p[i].v;
		sum += p[i].x;
		add1(p[i].x, p[i].x);
		add2(p[i].x, 1);
	}
	printf("%lld\n", ans);
	return 0;
}

  

以上是关于[BZOJ3378] [Usaco2004 Open]MooFest 狂欢节(树状数组)的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ3378] [Usaco2004 Open]MooFest 狂欢节(树状数组)

BZOJ 3357: [Usaco2004]等差数列

bzoj 3357: [Usaco2004]等差数列

bzoj3355[Usaco2004 Jan]有序奶牛*

BZOJ 3390 Usaco2004 Dec Bad Cowstractors 牛的报复

Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题