hdu 2492 Ping pong 线段树

给定一个序列,求出一共有多少个三元组(ai,aj,ak),使得i<j<k,ai<aj<ak。

固定中间值,查找前面比他大的有多少,比他小的有多少,查找后面比他大的有多少,比他小的有多少。

#include <stdio.h>
#include <string.h>
#define maxn 100200
#define N 20100
int sum[maxn*4];
int lmax[N],lmin[N],rmax[N],rmin[N];
int ans[N];
void pushup(int o)
{
    sum[o]=sum[o*2]+sum[o*2+1];
}

void build(int l,int r,int o)
{
    if(l==r)
    {
        sum[o]=0;
        return ;
    }
    else
    {
        int m=(l+r)/2;
        build(l,m,o*2);
        build(m+1,r,o*2+1);
        pushup(o);
    }
}

void update(int p,int l,int r,int o)
{
    if(l==r)
    {
        sum[o]++;
        return ;
    }
    int m=(l+r)/2;
    if(p<=m) update(p,l,m,o*2);
    else update(p,m+1,r,o*2+1);
    pushup(o);
}

int query(int L,int R,int l,int r,int o)
{
    if(L<=l && r<=R) return sum[o];
    int m=(l+r)/2,tot=0;
    if(L<=m) tot+=query(L,R, l,m,o*2);
    if(R>m) tot+=query(L,R, m+1,r,o*2+1);
    return tot;
}
int main()
{
    int cas;
    scanf("%d",&cas);
    int n;
    int i,j;
    while(cas--)
    {
        scanf("%d",&n);
        __int64 xx=0;
        for(i=1;i<=n;i++)
            scanf("%d",&ans[i]);
        build(1,maxn,1);
        for(i=1;i<=n;i++)
        {
            update(ans[i],1,maxn,1);
            lmax[i]=query(ans[i], maxn, 1, maxn, 1)-1;
            lmin[i]=query(1, ans[i], 1, maxn, 1)-1;
        }
        build(1,maxn,1);
        for(i=n;i>0;i--)
        {
            update(ans[i],1,maxn,1);
            rmax[i]=query(ans[i],maxn,1,maxn,1)-1;
            rmin[i]=query(1,ans[i],1,maxn,1)-1;
        }
        for(i=2;i<n;i++)
            xx=xx+lmin[i]*rmax[i]+rmin[i]*lmax[i];
        printf("%I64d\n",xx);
    }
    return 0;
}

hdu 2492 Ping pong 线段树

时间: 2024-10-09 06:50:44

hdu 2492 Ping pong 线段树的相关文章

POJ 3928 &amp; HDU 2492 Ping pong(树状数组求逆序数)

题目链接: PKU:http://poj.org/problem?id=3928 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=2492 Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To im

POJ 3928 &amp;amp; HDU 2492 Ping pong(树阵评价倒数)

主题链接: PKU:http://poj.org/problem?id=3928 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=2492 Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To im

HDU 2492 Ping pong (树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2492 Ping pong Problem Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To improve their skill rank

HDU 2492 Ping pong

题意: 一串数字  问  有几种这样的组合(x,y,z)使得x>y>z或x<y<z  y在x数字后面z在y后面  题目中每种数字是唯一的 思路: 对于一个数字  比如 f  它计算出的ans值为 ( beforef.lessthanf * afterf.biggerthanf )+( beforef.biggerthanf * afterf.lessthanf ) 易知 beforef.biggerthanf = locationf - 1 - beforef.lessthanf

【HDOJ】2492 Ping pong

线段树+离散化. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 #define MAXN 20005 6 #define lson l, mid, rt<<1 7 #define rson mid+1, r, rt<<1|1 8 9 int buf[MAXN], bk[MAXN]; 10 int sum[MAXN<<2], n; 11 12 int

HDU 4902 Nice boat(线段树)

HDU Nice boat 题目链接 题意:给定一个序列,两种操作,把一段变成x,把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 思路:线段树,每个结点多一个cover表示该位置以下区间是否数字全相同,然后每次延迟操作,最后输出的时候单点查询即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1

hdu 2795 Billboard(线段树)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10890    Accepted Submission(s): 4827 Problem Description At the entrance to the university, there is a huge rectangular billboard of

hdu 3016 Man Down (线段树 + dp)

题目大意: 是男人就下一般层...没什么可以多说的吧. 注意只能垂直下落. 思路分析: 后面求最大值的过程很容易想到是一个dp的过程 . 因为每一个plane 都只能从左边 从右边下两种状态. 然后我们所需要处理的问题就是 ,你如何能快速知道往左边下到哪里,往右边下到哪里. 这就是线段树的预处理. 讲线段按照高度排序. 然后按照高度从小到大加入到树中. 然后去寻找左端点 和 右端点最近覆盖的线段的编号. #include <cstdio> #include <iostream> #

HDU 3954 Level up 线段树

---NotOnlySuccess 出的题--- 看了题之后觉得和HDU 4027有点像,给的K很小,只有10,目测只要有人升级的时候直接更新到叶子节点就ok了.不过不同于HDU 4027 的是,那题每一次更新都相当于这题的一次升级操作,这题里面可能会出现一次操作之后没有升级和出现升级两种情况,一时半会没了思路. 无奈去搜题解,发现我只要维护一个区间当中距离升级最近的人所需要的基础升级经验,即不算等级加成的裸的升级经验,如果在一次涨经验之后,出现当前区间当中有人会升级,直接将每一个要升级的人更新