zoukankan      html  css  js  c++  java
  • [luogu]P2657低头一族[树状数组]

    [luogu]P2657

    低头一族

    题目描述

    一群青年人排成一队,用手机互相聊天。

    每个人的手机有一个信号接收指标,第i个人的接收指标设为v[i]。

    如果位置在x[i]的人要和位置在xj的人聊天,那么这两人组成的一对的信号发射强度就是abs(x[i]-x[j])*max(v[i],v[j]).

    现在我们想知道,这些人所有对子中的信号发射强度的总和。

    输入输出格式

    输入格式:
    第一行一个整数N,接下来N行,每行两个整数v[i]和x[i]。

    输出格式:
    所有对的信号发射强度总和。

    输入输出样例

    输入样例1#:
    4
    3 1
    2 5
    2 6
    4 3
    输出样例1#:
    57
    【说明】
    对于40%的数据,N<=5,000
    对于100%的数据,N<=100,000 1≤x[i]≤20,000
    注意:可能有两人在同一个位置
    答案在int64或long long范围内


    两点间距*两点价值最大
    考虑对答案贡献的是某一价值,那么就是要找寻比他小的。所以我们先按v进行排序。
    考虑用树状数组统计答案。
    用两个树状数组,一个记录(1...i)中的x坐标和,另一个是个数。
    那么这个点对答案的贡献为:
    v[i]*(getnum(x[i])*x[i]-getsum(x[i])+tot-getsum(x[i])-(i-getnum(x))*x[i])
    tot每次累加x[i]。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long ll ;
     7 inline int read();
     8 namespace lys{
     9     const int N = 2e4 + 7 ;
    10     struct LOW_head{
    11         int v;
    12         int x;
    13     }a[100007];
    14     ll bitS[N],bitN[N];
    15     int lowbit(int x){return x&(-x);}
    16     ll getS(int x){
    17         ll res=0;
    18         for(;x;x-=lowbit(x)) res+=bitS[x];
    19         return res ;
    20     }
    21     ll getN(int x){
    22         ll res=0;
    23         for(;x;x-=lowbit(x)) res+=bitN[x];
    24         return res ;
    25     }
    26     void insertS(int x,int y){for(;x<=N;x+=lowbit(x)) bitS[x]+=y;}
    27     void insertN(int x){for(;x<=N;x+=lowbit(x)) bitN[x]++;}
    28     bool cmp(const LOW_head &x,const LOW_head &y){return x.v<y.v;}
    29     int n;
    30     ll ans,tot;
    31     int main(){
    32         int i;
    33         n=read();
    34         for(i=0;i<n;i++) a[i].v=read(),a[i].x=read();
    35         sort(a,a+n,cmp);
    36         for(i=0;i<n;i++){
    37             ans+=1LL*a[i].v*(1LL*(2*getN(a[i].x)-i)*a[i].x-2*getS(a[i].x)+tot);
    38             tot+=a[i].x;
    39             insertS(a[i].x,a[i].x);
    40             insertN(a[i].x);
    41         }
    42         printf("%lld
    ",ans);
    43         return 0;
    44     }
    45 }
    46 int main(){
    47     lys::main();
    48     return 0;
    49 }
    50 inline int read(){
    51     int kk=0,ff=1;
    52     char c=getchar();
    53     while(c<'0'||c>'9'){
    54         if(c=='-') ff=-1;
    55         c=getchar();
    56     }
    57     while(c>='0'&&c<='9') kk=kk*10+c-'0',c=getchar();
    58     return kk*ff;
    59 }
  • 相关阅读:
    区块链开发之Corda训练营笔记12:Flow习题答案
    区块链开发之Corda训练营笔记11:Flow代码演示
    gitolite的部署
    python操作redis
    python多进程
    mysql索引
    mysql事务
    mysql外键
    mysql联合查询
    python常用模块之re模块(正则)
  • 原文地址:https://www.cnblogs.com/_inx/p/7928333.html
Copyright © 2011-2022 走看看