lgP5094 [USACO04OPEN]MooFest

好久没打cdq分治,都不太会了
有更简单地树状数组做法

#include<bits/stdc++.h>
#define MAXN 60005
typedef long long ll;
using namespace std;

ll n,ans;
struct node{ll v,x;}t[MAXN],p[MAXN];
bool cmp(node A , node B){return A.v < B.v;}


void solve(int l , int r){
	if(l == r)return;
	int mid = (l + r) >> 1;
	solve(l , mid);
	solve(mid + 1 , r);
	ll sum = 0 , cnt = 0 , sum2 = 0;
	int i = l , j = mid + 1 , len = l - 1;
	for(int k = l ; k <= mid ; k++)sum2 += t[k].x;
	while(i <= mid && j <= r){
		if(t[i].x <= t[j].x)sum += t[i].x , cnt++ , sum2 -= t[i].x , len++ , p[len] = t[i] , i++;
		else{
			ans = ans + (t[j].x * cnt - sum) * t[j].v , len++ , p[len] = t[j];
			ans = ans + (sum2 - (mid - l + 1 - cnt) * t[j].x) * t[j].v;	
			j++;
		}
	}
	while(i <= mid){
		sum += t[i].x , cnt++ , sum2 -= t[i].x , len++ , p[len] = t[i] , i++;
	}
	while(j <= r){
		ans = ans + (t[j].x * cnt - sum) * t[j].v , len++ , p[len] = t[j];
		ans = ans + (sum2 - (mid - l + 1 - cnt) * t[j].x) * t[j].v;	
		j++;
	}
	for(int i = l ; i <= r ; i++)t[i] = p[i];
}

int main(){
	scanf("%d" , &n);
	for(int i = 1 ; i <= n ; i++)scanf("%lld%lld" , &t[i].v , &t[i].x);
	sort(t + 1 , t + 1 + n , cmp);
	solve(1 , n);
	cout<<ans<<endl;
}
posted @ 2021-11-01 20:35  After_rain  阅读(39)  评论(0)    收藏  举报