• POJ


    题目链接

    题意:

    给定 $N$ 头牛的位置$(x)$和听力阈值$(v)$,每两头牛之间交流需要的声音是 $max( v1, v2) * | x1 - x2 |$ ,现在要求所有牛之间交流的声音总值。

    思路:

    对于每两头牛之间,总是取最大的$V$ , 我们就可以按照$V$的大小排序;

    那么我们就可以用当前牛的 $V *$ 已经存在的牛到当前牛的距离总和 ,并更新答案。

    这里要用树状数组记录一下  下标之和 $and$ 个数 ,于是我们就两个树状数组。

     1 /*
     2 * @Author: windystreet
     3 * @Date:   2018-08-07 15:13:40
     4 * @Last Modified by:   windystreet
     5 * @Last Modified time: 2018-08-07 15:52:16
     6 */
     7 #include<stdio.h>
     8 #include<string.h>
     9 #include<algorithm>
    10 
    11 using namespace std;
    12 
    13 #define X first
    14 #define Y second
    15 #define eps  1e-5
    16 #define gcd __gcd
    17 #define pb push_back
    18 #define PI acos(-1.0)
    19 #define lowbit(x) (x)&(-x)
    20 #define bug printf("!!!!!
    ");
    21 #define mem(x,y) memset(x,y,sizeof(x))
    22 
    23 typedef long long LL;
    24 typedef long double LD;
    25 typedef pair<int,int> pii;
    26 typedef unsigned long long uLL;
    27 
    28 const int maxn = 2e4+7;
    29 const int INF  = 1<<30;
    30 const int mod  = 1e9+7;
    31 
    32 struct node
    33 {
    34     int x,v;
    35 }s[maxn];
    36 
    37 LL tree[maxn][3];     // 0 下标和
    38 int n;                // 1  个数
    39 
    40 bool cmp(node a,node b){
    41     return a.v<b.v||(a.v==b.v&&a.x<b.x);
    42 }
    43 
    44 
    45 void add(int x,int v,int flag){
    46     for(int i=x;i<maxn;i+= lowbit(i)){
    47         tree[i][flag] += v;
    48     }
    49     return ;
    50 }
    51 LL query(int x,int flag){
    52     LL res = 0;
    53     for(int i=x;i;i-=lowbit(i)){
    54         res += tree[i][flag];
    55     }
    56     return res;
    57 }
    58 
    59 
    60 void solve(){
    61     scanf("%d",&n);
    62     for(int i=1;i<=n;i++){
    63         scanf("%d%d",&s[i].v,&s[i].x);
    64     }
    65     sort(s+1,s+1+n,cmp);
    66     LL ans = 0,a1,a2,b1,b2;
    67     for(int i=1;i<=n;i++){
    68         a1 = query(s[i].x,0);         // s[i].x之前的牛的下标和
    69         a2 = query(maxn-1,0) - a1;    // 所有的牛的下标和
    70         b1 = query(s[i].x,1);         // s[i].x之前的牛的数量
    71         b2 = query(maxn-1,1) - b1;    // 所有牛的数量
    72         ans += (b1*s[i].x - a1 + a2 - s[i].x * b2) * s[i].v;  
    73         add(s[i].x,s[i].x,0);         // b1 * s[i].x - a1 表示s[i].x 之前的牛到s[i].x 的距离之和
    74         add(s[i].x,1,1);              // a2 - s[i].x * b2 表示s[i].x 之后的牛到s[i].x 的距离之和
    75 
    76     }
    77     printf("%lld
    ",ans);
    78 
    79     return;
    80 }
    81 
    82 int main()
    83 {
    84 //    freopen("in.txt","r",stdin);
    85 //    freopen("out.txt","w",stdout);
    86 //    ios::sync_with_stdio(false);
    87     int t = 1;
    88     //scanf("%d",&t);
    89     while(t--){
    90     //    printf("Case %d: ",cas++);
    91         solve();
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    C#深复制和浅复制
    C#程序设计六大原则记录
    C#异步
    线程同步
    线程基础
    委托,事件
    XmlSerializer
    C#接口
    C#封装
    C#多态
  • 原文地址:https://www.cnblogs.com/windystreet/p/9437853.html
Copyright © 2020-2023  润新知