本质上是一道统计点对之间贡献的题目。

将每个奶牛看作一个点对\((v_i,x_i)\),\(i\)能对\(j\)产生贡献,当且仅当下面条件其一成立:

  • \(v_i\le v_j,x_i>x_j\),此时的贡献为\((x_i-x_j)\times v_j\)。
  • \(v_i\le v_j,x_i<x_j\),此时的贡献为\((x_j-x_i)\times v_j\)。

大体思路是这样,有不同的实现方法。

Sol #1 树状数组

根据上面的分析,我们可以将点对按\(v\)从小到大排序,依次遍历,将\(x\)丢进树状数组。

\(i\)之前的\(x\)被丢进树状数组后,统计对\(i\)的贡献。

  • 先查树状数组中\(x\in [1,x_i-1]\)的\(x\)之和,记为\(s\),这样的\(x\)的个数记为\(c\),对答案的贡献即为\((c\times x_i-s)\times v_i\);
  • 再查\([x_i+1,+\infty]\),对答案的贡献为\((s-c\times x)\times v_i\)。

时间复杂度\(O(n\log V)\),其中\(V\)是值域。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e4+10,Ve=5e4,V=Ve+10;//e=exact
int n,ans;
inline int lb(int x){return x&-x;}
struct BIT{
int s[V],c[V];
void chp(int x,int v){for(;x<=Ve;x+=lb(x)) s[x]+=v,c[x]++;}
void qry(int x,int y,int& _s,int& _c){
_s=_c=0,x--;
for(;y;y-=lb(y)) _s+=s[y],_c+=c[y];
for(;x;x-=lb(x)) _s-=s[x],_c-=c[x];
}
}bit;
struct Node{int a,v;}a[N];
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].v>>a[i].a;
sort(a+1,a+1+n,[](Node a,Node b){return a.v<b.v;});
for(int i=1,s,c;i<=n;i++){
bit.qry(1,a[i].a-1,s,c);
ans+=a[i].v*(c*a[i].a-s);
bit.qry(a[i].a+1,Ve,s,c);
ans+=a[i].v*(s-c*a[i].a);
bit.chp(a[i].a,a[i].a);
}
cout<<ans<<"\n";
return 0;
}

Sol #2 CDQ分治

统计点对贡献,当然少不了CDQ分治~

不妨对\(v\)分治,按照\(x\)合并。

具体来说,将\(v\)从小到大排序,然后从\([1,n]\)开始不断分成左右两个区间递归处理,每个子问题只计算跨区间的贡献。这也是CDQ分治的核心思想。

递归处理完左右子问题后,将左右区间内部按\(x\)从小到大排序,尽管\(v\)的顺序已经被打乱,但是由于是区间内部的排序,所以左区间的\(v\)值始终\(\le\)右区间的\(v\)值。仅需关心\(x\)之间的关系。

我们用双指针\(i,j\)分别指向左右区间,\(j\)每次移动之前,\(i\)都移动到最大的位置使得\(x_i<x_j\)。这样\([l,i]\)的点对满足第二个条件,\([i+1,mid]\)的点对满足第一个条件。对照式子统计即可。

按\(x\)排序的过程如果写成sort会是\(O(n\log^2 n)\)的,可以在递归的同时进行归并排序,这样就可以降到\(O(n\log n)\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e4+10;
int n,ans;
struct Node{int a,v;}a[N],t[N];
int cdq(int l,int r){//返回值为[l,r]内a的和
if(l==r) return a[l].a;
int mid=(l+r)>>1,i,j,k,s=0,sl=cdq(l,mid),sr=cdq(mid+1,r);
for(i=k=l,j=mid+1;j<=r;j++){
while(i<=mid&&a[i].a<a[j].a) s+=a[i].a,t[k++]=a[i++];
ans+=a[j].v*(((i-l)*a[j].a-s)+((sl-s)-(mid+1-i)*a[j].a));
t[k++]=a[j];
}
while(i<=mid) t[k++]=a[i++];
for(i=l;i<=r;i++) a[i]=t[i];
return sl+sr;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].v>>a[i].a;
sort(a+1,a+1+n,[](Node a,Node b){return a.v<b.v;});
cdq(1,n);
cout<<ans<<"\n";
return 0;
}

[题解]P5094 [USACO04OPEN] MooFest G 加强版的更多相关文章

  1. P2345 [USACO04OPEN] MooFest G

    简单的一个分块处理:优雅的暴力枚举 #include<bits/stdc++.h>using namespace std; typedef long long ll;const int N ...

  2. ACM ICPC 2018 青岛赛区 部分金牌题题解(K,L,I,G)

     目录: K Airdrop I Soldier Game L Sub-cycle Graph G Repair the Artwork ———————————————————— ps:楼主脑残有点严 ...

  3. luoguP5094 [USACO04OPEN]MooFest 狂欢节

    get 到的 这种需要求 含 max 的式子,枚举最大值的方法非常普遍. 类似的,还有含 min , gcd 的式子,枚举他们也很普遍 主要难点 我们首先想到,先按 v 从小到大排序,因为这样既可以简 ...

  4. 【题解】[USACO07OPEN]Dining G

    \(Link\) \(\text{Solution:}\) 这一题,我们要做到,食物和牛.牛和饮料均为一对一的关系.我们发现这个图不好建立. 经典技巧:将牛拆边,拆成入点和出点,并连容量为\(1\)的 ...

  5. 【题解】[USACO07NOV]Sunscreen G

    \(Link\) \(\text{Solution:}\) 把奶牛的忍耐度转化为线段,则题目转化为选择一些点使得覆盖的线段尽可能多.一个点只能覆盖一条线段. 考虑将点按照位置排序,线段按照右端点排序. ...

  6. [题解] [USACO05JAN]Muddy Fields G

    题目TP门 题目大意 在一个 \(R×C\) 的矩阵中,每个点有两个状态:草地和泥地.你需要在泥地里铺 \(1×k\) 木块, \(k\) 为任意整数,求最少要多少木块. 思路 两个横向木块不会互相干 ...

  7. 【BZOJ】2277: [Poi2011]Strongbox

    题意 有一个密码箱,\(0\)到\(n-1\)中的某些整数是它的密码.如果\(a\)和\(b\)都是它的密码,那么\((a+b)%n\)也是它的密码(\(a,b\)可以相等).某人试了\(k\)次密码 ...

  8. POJ2429 - GCD & LCM Inverse(Miller–Rabin+Pollard's rho)

    题目大意 给定两个数a,b的GCD和LCM,要求你求出a+b最小的a,b 题解 GCD(a,b)=G GCD(a/G,b/G)=1 LCM(a/G,b/G)=a/G*b/G=a*b/G^2=L/G 这 ...

  9. CH Round #54 - Streaming #5 (NOIP模拟赛Day1)

    A.珠 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2354%20-%20Streaming%20%235%20(NOIP模拟赛Day1)/珠 题解:sb题, ...

  10. Largest Submatrix(动态规划)

    Largest Submatrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

随机推荐

  1. Linux日志 查找关键字及其前后的信息

      文章<五分钟扫盲:25个工作中常用的Linux命令>介绍了常用的Linux命令,属于理论知识,这里知行合一,介绍如何从Linux日志中通过关键字过滤出我们需要的信息.   这里以查看名 ...

  2. Fiddler抓包工具安装HTTPS证书

    安装好之后,打开Fiddler根目录,打开CMD 执行以下内容 makecert.exe -r -ss my -n "CN=DO_NOT_TRUST_FiddlerRoot, O=DO_NO ...

  3. MySQL索引完全指南:让你的查询速度飞起来

    MySQL索引完全指南:让你的查询速度飞起来 还在为数据库查询慢而头疼吗?一个简单的索引就能让你的查询速度提升几十倍甚至上百倍!今天我将用最通俗易懂的方式,带你彻底搞懂MySQL索引的奥秘.从什么是索 ...

  4. 学习spring cloud记录2-在项目中使用mybatis-plus

    前言 本记录详细记录本人学习spring cloud继承mybatis plus方法,适用于初学者. 项目结构简单介绍 本系统目前新建两个dmeo服务,分别是demo-user和demo-order两 ...

  5. Macbook装Window后触摸滑动方向反

    找到设备id 可以看到我的是: VID_05ac&PID_0276&MI_02&Col01\6&8d58d53&0&0000 如果有多个,可以在常规&g ...

  6. N1的openwrt的docker下安装homeassistant

    docker配置 Docker>配置 修改默认桥接的地址为路由器ip(如果n1作为旁路由的话 则则这里填写主路由的ip) 获取docker镜像 拉取homeassistant最新docker镜像 ...

  7. react-router v6 路由

    前言 之前写react的时候 路由真的是难用,这次更新后,极为好用! 嵌套路由 main.jsx import './index.css'; import * as React from 'react ...

  8. 卸载vivo或iqoo或其它手机的预装软件

    前言 众说周知,现在安卓手机做的越来越闭源,(除了一加和小米以及红蓝厂的部分型号 大部分)根本无法root. 那就意味着 手机上一些预装的软件 根本无法卸载 比如:阅读.xx官网.自带的视频和音乐软件 ...

  9. 前端开发系列134-进阶篇之脚手架Yue-cli的实现03-download功能

    这是系列文章前端脚手架实现的第三篇,本文核心解决当我们通过模板来初始化项目时如何把选定版本的模板文件下载到对应文件夹中的问题. 当我们在拉取模板文件的时候,存在两种情况,一种是直接把初始化项目的模板文 ...

  10. opengl 学习 之 12 lesson

    opengl 学习 之 12 lesson 简介 扩展函数值DEBUG!!! link http://www.opengl-tutorial.org/uncategorized/2017/06/07/ ...