zoukankan      html  css  js  c++  java
  • Luogu2345 | 奶牛集会 (树状数组)

    题目背景

    MooFest, 2004 Open

    题目描述

    约翰的 (N) 头奶牛每年都会参加“哞哞大会”。哞哞大会是奶牛界的盛事。集会上的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等。它们参加活动时会聚在一起,第i 头奶牛的坐标为 (Xi),没有两头奶牛的坐标是相同的。奶牛们的叫声很大,第i 头和第j 头奶牛交流,会发出 (max[Vi,Vj]×|Xi−Xj|) 的音量,其中 (Vi)(Vj) 分别是第 (i) 头和第 (j) 头奶牛的听力。

    假设每对奶牛之间同时都在说话,请计算所有奶牛产生的音量之和是多少。

    输入格式

    • 第一行:单个整数 (N) ((1 ≤ N ≤ 20000))

    • 第二行到第N + 1 行:第i + 1 行有两个整数 (Vi)(Xi) ((1 ≤ Vi ≤ 20000,1 ≤ Xi ≤ 20000))

    输出格式

    • 单个整数:表示所有奶牛产生的音量之和

    输入输出样例

    输入 #1

    4
    3 1
    2 5
    2 6
    4 3

    输出 #1

    57

    ————————————————————————————————————
    音量的计算公式 (max[Vi,Vj]×|Xi−Xj|) 看起来很友好,

    由于奶牛两两之间都会发出声音,很容易想到先将奶牛按 (Vi) 升序排序,之后每遍历到一只奶牛,就计算这只奶牛与此前出现的所有奶牛发出的音量,统计进答案中即可。

    这样我们需要求的就是当前奶牛与此前出现的所有奶牛的距离之和,即 (sum_{j=1}^{i-1}dis(i,j))

    上面的这个式子是 (O(N^2)) 的,而我们需要在 (O(logn)) 的时间内解决,所以可以使用支持单点修改和区间查询的树状数组优化,

    这里使用了两个树状数组,分别存储了奶牛的个数奶牛的坐标和(即到原点的距离和)

    接下里我们把坐标小于当前奶牛和坐标大于当前奶牛的分开处理,具体计算公式请见代码。

    最后别忘了把这个值乘上当前奶牛的 (Vi)再 统计进答案,之后还要把当前奶牛的数值加入两个树状数组中。

    PS:还要开(long long)

    代码如下:

    #include <bits/stdc++.h>
    #define FOR(i,s,t) for (ll (i)=(s);(i)<=(t);(i)++)
    #define lowbit(x) ((x)&(-x))
    #define ll long long
    #define MAXN 20007
    #define MAXX 20007
    using namespace std;
    struct cow { ll v,x; }p[MAXN];
    ll c1[MAXN],c2[MAXN],n,ans=0;
    inline bool cmp(const cow &A,const cow &B) { return A.v<B.v; }
    inline void add(ll x) { for (ll i=x;i<MAXX;i+=lowbit(i)) c1[i]++,c2[i]+=x; }
    inline ll q1(ll x) {
    	ll ret=0;
    	for (ll i=x;i>=1;i-=lowbit(i)) ret+=c1[i];
    	return ret;
    }
    inline ll q2(ll x) {
    	ll ret=0;
    	for (ll i=x;i>=1;i-=lowbit(i)) ret+=c2[i];
    	return ret;
    }
    inline ll read() {
    	ll X=0,w=0; char ch=0;
    	while (!isdigit(ch)) w|=ch=='-',ch=getchar();
    	while (isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    	return w?-X:X;
    }
    int main() {
    	memset(c1,0,sizeof(c1));
    	memset(c2,0,sizeof(c2));
    	n=read(); FOR(i,1,n) p[i].v=read(),p[i].x=read();
    	sort(p+1,p+n+1,cmp);
    	FOR(i,1,n) {
    		ll amt1=q1(p[i].x-1),dis1=amt1*p[i].x-q2(p[i].x-1);
    		ll amt2=q1(MAXX-1)-q1(p[i].x),dis2=q2(MAXX-1)-q2(p[i].x-1)-amt2*p[i].x;
    		ans+=(dis1+dis2)*p[i].v,add(p[i].x);
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    spring-AnnotationConfigApplicationContext源码阅读
    图解http pdf
    paasone的创新(2):separated langsysdemo ecosystem及demo driven debug
    Plan9:一个从0开始考虑分布式,分布appmodel的os设计
    terra++
    qtcling
    terracling:前端metalangsys后端uniform backend免编程binding生成式语言系统设想
    ubuntu touch: deepin pc os和deepin mobile os的天然融合
    windows版gbc:基于enginx的组件服务器系统paas,可用于mixed web与websocket game
    WinPE VirtIO云主机版 支持west263 阿里云aliyun 送精简win2k3镜像
  • 原文地址:https://www.cnblogs.com/zhwer/p/12240000.html
Copyright © 2011-2022 走看看