cf 61 E. Enemy is weak 离散化+树状数组

题意:

给出一个数组,数组的每一个元素都是不一样的,求出对于3个数组下标 i, j, k such that i < j < k and ai > aj > ak where ax is the value at position x.  的个数

明显数组的值太大了

先离散化,然后就是简单的树状数组了

对于每一个i,只要统计i前面的数中比a[i]大的数的个数,和i后面的数中比a[i]小的数的个数即可

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <math.h>

#define LL long long

using namespace std;

const int maxn = 1000000 + 10;

struct Node
{
    int id,init,chg;
};
Node node[maxn];
int fir[maxn];
int sec[maxn];
int c[maxn];

bool cmp1(Node x,Node y)
{
    return x.init<y.init;
}

bool cmp2(Node x,Node y)
{
    return x.id<y.id;
}

inline int lb(int x)
{
    return x & (-x);
}

void update(int x,int add)
{
    while(x <= maxn){
        c[x] += add;
        x += lb(x);
    }
}

int query(int x)
{
    int ret = 0;
    while(x > 0){
        ret += c[x];
        x -= lb(x);
    }
    return ret;
}

LL solve(int n)
{
    sort(node+1,node+n+1,cmp1);
    for(int i=1;i<=n;i++)
        node[i].chg = i;
    sort(node+1,node+n+1,cmp2);
    memset(c,0,sizeof c);
    for(int i=1;i<=n;i++){
        fir[i] = i - 1 - query(node[i].chg - 1);
        update(node[i].chg,1);
    }
    memset(c,0,sizeof c);
    for(int i=n;i>0;i--){
        sec[i] = query(node[i].chg - 1);
        update(node[i].chg,1);
    }
    LL ret = 0;
    for(int i=1;i<=n;i++)
        ret += (LL) fir[i] * sec[i];
    return ret;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&node[i].init);
        node[i].id = i;
    }
    //printf("%I64d\n",solve(n));
    cout<<solve(n)<<endl;
    return 0;
}
时间: 2025-01-03 03:44:01

cf 61 E. Enemy is weak 离散化+树状数组的相关文章

hdu 3015 Disharmony Trees (离散化+树状数组)

Disharmony Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 663    Accepted Submission(s): 307 Problem Description One day Sophia finds a very big square. There are n trees in the square. T

hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 481    Accepted Submission(s): 245 Problem Description You were driving along a highway when you got caught by the road p

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

poj 2299 Ultra-QuickSort 离散化 + 树状数组

题目链接:http://poj.org/problem?id=2299 离散化 + 树状数组 教科书例题般的题目 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <vector> #include <stack> #include <set> #include

CodeForces 540E - Infinite Inversions(离散化+树状数组)

花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树状数组,但是发现那些没有交换的数也会产生逆序对数,但我没有算. 经明神提示, 把没有用到的数字段化成点.然后用树状数组算一下就好了. 然后我用一个数组记录每个点的长度.比如 <1,2><5,6>,1,2,3,4,5,6只有1,2,5,6用到了,那么离散化为1,2,3,4,5,f[1]=

【bzoj4756】[Usaco2017 Jan]Promotion Counting 离散化+树状数组

原文地址:http://www.cnblogs.com/GXZlegend/p/6832263.html 题目描述 The cows have once again tried to form a startup company, failing to remember from past experience that cows make terrible managers!The cows, conveniently numbered 1-N1-N (1≤N≤100,000), organi

POJ 2299 Ultra-QuickSort (离散化+树状数组)

题目链接:POJ 2299 Ultra-QuickSort 求一串序列相邻连个元素交换多少后,是一串上升的序列. 思路:求该串序列的逆序数,数据比较大,要离散化. AC代码: #include<stdio.h> #include<string.h> #include<set> #include<map> #include<algorithm> #define ll __int64 using namespace std; const ll max

CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点值离散化,按照左端点从大到小排序,顺着这个顺序处理所有线段,那么满足在它内部的线段一定是之前已经扫到过的.用树状数组判断有多少是在右端点范围内. 1 #include <iostream> 2 #include <vector> 3 #include <algorithm>

uestc oj 1217 The Battle of Chibi (dp + 离散化 + 树状数组)

题目链接:http://acm.uestc.edu.cn/#/problem/show/1217 给你一个长为n的数组,问你有多少个长度严格为m的上升子序列. dp[i][j]表示以a[i]结尾长为j的上升子序列个数.常规是三个for. 这里用树状数组优化一下,类似前缀和的处理,两个for就好了. 1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #incl