P2345 [USACO04OPEN] MooFest G
简单的一个分块处理:优雅的暴力枚举
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e4 + 7;
int st[N];
struct Block {
int l, r;
ll sum, m;
} block[151];
struct Node {
ll v, x;
} a[N];
bool cmp ( Node x, Node y ) {
if(x.v == y.v) return x.x < y.x;
return x.v < y.v;
}
void build ( ll n ) {
ll p = sqrt ( n );
ll t = n/p;
if( p * t < n ) t ++;
for( int i = 1;i <= t;i ++ ) {
block[i].l = ( i - 1 ) * p;
block[i].r = i * p;
block[i].m = block[i].sum = 0;
}
block[t].r = n;
}
ll find ( int q, ll n ) {
ll ans = 0, sum = 0, m = 0;
ll t = sqrt ( n );
ll k = n / t;
if(k * t < n) k ++;
t = a[q].x / t + (a[q].x % t != 0); int p = 0;
for( p = 1;p < t;p ++ )
m += block[p].m, sum += block[p].sum;
for( int j = block[t].l + 1;j < a[q].x;j ++ )
if(st[j])
m ++, sum += j;
ans += a[q].v * ( m * a[q].x - sum );
st[a[q].x] = 1;
block[p].m ++, block[p].sum += a[q].x;
m = sum = 0;
for( int j = a[q].x + 1; j <= block[p].r;j ++ )
if(st[j])
m ++, sum += j;
for( p += 1; p <= k; p ++ )
m += block[p].m, sum += block[p].sum;
ans += a[q].v * ( sum - m * a[q].x );
return ans;
}
int main() {
int n;
ll ans = 0;
scanf ( "%d", &n );
ll maxx = 0;
for(int i = 1;i <= n;i ++) {
scanf ( "%lld%lld", &a[i].v, &a[i].x );
maxx = max ( maxx, a[i].x );
}
build ( maxx );
sort ( a + 1, a + n + 1, cmp );
for( int i = 1;i <= n;i ++ )
ans += find ( i, maxx );
printf ( "%lld", ans );
return 0;
}

浙公网安备 33010602011771号