POJ1990 MooFest

Posted mrclr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1990 MooFest相关的知识,希望对你有一定的参考价值。

嘟嘟嘟

 

题目大意:一群牛参加完牛的节日后都有了不同程度的耳聋(汗……),第i头牛听见别人的讲话,别人的音量必须大于v[i],当两头牛i,j交流的时候,交流的最小声音为max{v[i],v[j]}*他们之间的距离。现在有n头牛,求他们之间两两交流最少要的音量和。

 

首先我们把v[i]从小到大排序,这样扫的时候max(v[i], v[j]) == v[i] (j < i)了。同时为了重复计算,我们只统计j < i的牛和 i 配对对答案的贡献。

关键是解决距离的绝对值的问题。用两个树状数组维护。

一个求对于当前的 i,dis[j] < dis[i]的牛有几头(cnt),一个维护这些牛的Σval(_sum)。这样对于那些dis[j] < dis[i]的牛,对答案的贡献就是val[i] * (cnt * dis[i] - _sum)。对于那些dis[j] > dis[i]的牛,我们还要开一个全局变量sum,表示当前的Σval[i],那么这这 j 头牛的sum‘ = sum - _sum, cnt‘ = (i - 1 - cnt),所以这部分牛对答案的贡献就是val[i] * (sum‘ - cnt‘ * dis[i])。最后把两部分相加。

技术分享图片
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(‘ ‘)
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const int maxn = 2e4 + 5;
21 inline ll read()
22 {
23   ll ans = 0;
24   char ch = getchar(), last =  ;
25   while(!isdigit(ch)) {last = ch; ch = getchar();}
26   while(isdigit(ch)) {ans = ans * 10 + ch - 0; ch = getchar();}
27   if(last == -) ans = -ans;
28   return ans;
29 }
30 inline void write(ll x)
31 {
32   if(x < 0) x = -x, putchar(-);
33   if(x >= 10) write(x / 10);
34   putchar(x % 10 + 0);
35 }
36 
37 int n;
38 ll sum = 0, ans = 0;
39 struct Node
40 {
41   int val, id;
42   bool operator < (const Node &oth)const
43   {
44     return val < oth.val || (val == oth.val && id < oth.id);
45   }
46 }a[maxn];
47 
48 struct Bit
49 {
50   ll c[maxn];
51   Bit() {Mem(c, 0);}
52   int lowbit(int x)
53   {
54     return x & -x;
55   }
56   void add(int pos, int d)
57   {
58     for(; pos < maxn; c[pos] += d, pos += lowbit(pos));
59   }
60   ll query(int pos)
61   {
62     ll ret = 0;
63     for(; pos; ret += c[pos], pos -= lowbit(pos));
64     return ret;
65   }
66 }C1, C2;
67 
68 int main()
69 {
70   n = read();
71   for(int i = 1; i <= n; ++i) a[i].val = read(), a[i].id = read();
72   sort(a + 1, a + n + 1);
73   for(int i = 1; i <= n; ++i)
74     {
75       int cnt = C1.query(a[i].id), _sum = C2.query(a[i].id);
76       C1.add(a[i].id, 1); C2.add(a[i].id, a[i].id);
77       ll tot =  cnt * a[i].id - _sum;
78       tot += sum - _sum - (i - cnt - 1) * a[i].id;
79       ans += tot * a[i].val;
80       sum += a[i].id;
81     }
82   write(ans); enter;
83   return 0;
84 }
View Code

 

以上是关于POJ1990 MooFest的主要内容,如果未能解决你的问题,请参考以下文章

POJ1990 MooFest

POJ 1990 MooFest

POJ 1990 MooFest

MooFest POJ - 1990 树状数组

MooFest POJ - 1990 (树状数组)

POJ 1990 MooFest