【洛谷】2345 奶牛集会 树状数组

22 篇文章 0 订阅
13 篇文章 0 订阅

题目传送门

题目描述:……摸牛仔的屁股……。话说这不是LYF最喜欢的游戏吗?

考虑题目给出的公式, max(Vi,Vj)|XiXj| ,我们可以 V 作为关键字排序,消除V对统计答案的影响。这里我把 V 从小到大排序。

然后考虑绝对值,如果Xi>Xj,那么去掉绝对值就是 XiXj ;否则就是 XiXj 。(这TMD不是废话吗?)

但是!这个结论是非常有用的!接着往下看就知道了。

对于一头奶牛 i ,这头奶牛显然为当前所有计算过的奶牛中V最大的奶牛,发现这头奶牛对答案的贡献为 V(xggi=1x[i]+ig1i=1x[i]x(ig1)) ,其中 g 为比当前的奶牛坐标小的奶牛的头数。

显然上述的公式中的g x[i] 可以用两个树状数组来维护。这里我们把原来需要 O(n) 求的绝对值用 O(logn) 的树状数组替换掉了,成功节省了时间。这个拆绝对值的思想也是非常不错的。

于是这题就被愉快的A掉啦。

附上AC代码:

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;

const int N=2e4+10;
struct note{
    int v,x;
    bool operator < (const note lyf) const {return v<lyf.v;}
}a[N];
int n,m,sum[N],num[N];
long long ans;

inline char nc(){
    static char ch[100010],*p1=ch,*p2=ch;
    return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}

inline void read(int &a){
    static char c=nc();int f=1;
    for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
    for (a=0;isdigit(c);a=a*10+c-'0',c=nc());
    return (void)(a*=f);
}

#define lowbit(x) ((x)&(-x))
inline int query(int *t,int x){int sum=0; for (int i=x; i; i-=lowbit(i)) sum+=t[i]; return sum;}
inline void add(int *t,int x,int w){for (int i=x; i<=m; i+=lowbit(i)) t[i]+=w; return;}

int main(void){
    read(n);
    for (int i=1; i<=n; ++i) read(a[i].v),read(a[i].x),m=max(m,a[i].x);
    sort(a+1,a+1+n);
    for (int i=1; i<=n; ++i){
        int numl=query(num,a[i].x-1);
        int suml=query(sum,a[i].x-1);
        int numr=query(num,m)-query(num,a[i].x);
        int sumr=query(sum,m)-query(sum,a[i].x);
        ans+=1ll*a[i].v*(sumr-a[i].x*numr+a[i].x*numl-suml);
        add(num,a[i].x,1),add(sum,a[i].x,a[i].x);
    }
    return printf("%lld\n",ans),0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值