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

posted @   feuerwerk  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示