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;
}

浙公网安备 33010602011771号