Codeforces Round #261 (Div. 2) D. Pashmak and Parmida's problem (树状数组)

D. Pashmak and Parmida‘s problem

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants her partner to be clever too (although he‘s not)! Parmida has prepared the following test problem for Pashmak.

There is a sequence a that consists of
n integers a1,?a2,?...,?an. Let‘s denote
f(l,?r,?x) the number of indices
k such that: l?≤?k?≤?r and
ak?=?x. His task is to calculate the number of pairs of indicies
i,?j (1?≤?i?<?j?≤?n) such that
f(1,?i,?ai)?>?f(j,?n,?aj).

Help Pashmak with the test.

Input

The first line of the input contains an integer n
(1?≤?n?≤?106). The second line contains
n space-separated integers
a1,?a2,?...,?an
(1?≤?ai?≤?109).

Output

Print a single integer — the answer to the problem.

Sample test(s)

Input

7
1 2 1 1 2 2 1

Output

8

Input

3
1 1 1

Output

1

Input

5
1 2 3 4 5

Output

0

解析:f(l,?r,?x) 表示
l?≤?k?≤?r and
ak?=?x的个数,要计算 
f(1,?i,?ai)?>?f(j,?n,?aj),且i,?j
(1?≤?i?<?j?≤?n) 的对数.

先预处理f(1, i, ai)和f(j, n, aj),然后就特别像逆序数了。用树状数组搞一下就行了。

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;

int a[N], f[N], g[N], c[N];

map<int, int> m;

int lowbit(int x){
    return x & -x;
}

void add(int x, int d){
    for( ; x < N; x += lowbit(x)) c[x] += d;
}

int sum(int x){
    int ret = 0;
    for( ; x > 0; x -= lowbit(x)) ret += c[x];
    return ret;
}

int main(){
    #ifdef sxk
        freopen("in.txt", "r", stdin);
    #endif // sxk

    int n;
    while(~scanf("%d", &n)){
        m.clear();
        for(int i=1; i<=n; i++){
            scanf("%d", &a[i]);
            m[ a[i] ] ++;
            f[i] = m[ a[i] ];        //f(1, i, ai)
        }
        m.clear();
        for(int i=n; i>0; i--){
            m[ a[i] ] ++;
            g[i] = m[ a[i] ];        //f(j, n, aj)
        }
        memset(c, 0, sizeof(c));
        long long ans = 0;
        for(int i=n-1; i>0; i--){
            add(g[i+1], 1);
            ans += sum(f[i] - 1);
        }
        printf("%lld\n", ans);

    }
    return 0;
}

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida's problem (树状数组)

时间: 2024-08-29 00:06:55

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida's problem (树状数组)的相关文章

Codeforces Round 261 Div.2 D Pashmak and Parmida&#39;s problem --树状数组

题意:给出数组A,定义f(l,r,x)为A[]的下标l到r之间,等于x的元素数.i和j符合f(1,i,a[i])>f(j,n,a[j]),求有多少对这样的(i,j). 解法:分别从左到右,由右到左预处理到某个下标为止有多少个数等于该下标,用map维护. 然后树状数组更新每个f(j,n,a[j]),预处理完毕,接下来,从左往右扫过去,每次从树状数组中删去a[i],因为i != j,i不能用作后面的统计,然后统计getsum(inc[a[i]]-1), (inc表示从左到右),即查询比此时的a[i]

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida&#39;s problem (树状数组求逆序数 变形)

题目链接 题意: 给出一些数a[n],求(i, j), i<j 的数量,使得:f(1, i, a[i]) > f(j, n, a[j]) . f(lhs, rhs, x) 指在 { [lhs, rhs]范围中,a[k]的值=x } 的数量. 1.  f(1, i, a[i]) 就是指a[i]前面包括a[i]的数中,有几个值=a[i]. 2.  f(j, n, a[j]) 就是指a[j]后面包括a[j]的数中有几个值=a[j]. 虽然a[x]范围不小,但是n的范围是1000,不是很大,所以我们可

Codeforces Round #261 (Div. 2)459D. Pashmak and Parmida&#39;s problem(求逆序数对)

题目链接:http://codeforces.com/contest/459/problem/D D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Parmida is a clever girl and she wants to participate in O

Codeforces 459D Pashmak and Parmida&#39;s problem(树状数组)

题目链接:Codeforces 459D Pashmak and Parmida's problem 题目大意:给定一个序列,定义f(l,r,x)为l≤k≤r并且ak=x的k的个数,求1≤i<j≤n的情况下,f(1,i,ai)<f(j,n,aj)的个数. 解题思路:预处理出f(1,i,ai),f(j,n,aj)值,然后用树状数组维护个数. #include <cstdio> #include <cstring> #include <algorithm> us

Codeforcecs 459D Pashmak and Parmida&#39;s problem 树状数组 OR 分治

http://codeforces.com/contest/459/problem/D 题意:定义:f(l,r,x) [l,r]内x的个数 ,n个数,a[i] n<=1e5,a[i]<=1e9 问i<j时满足f(1,i,a[i]) > f(j,n,a[j]) 的(i,j)对数? 预处理出后缀f(j) 插入到BIT中 枚举i,查询mp[a[i]]-1,后更新BIT即可. #include <bits/stdc++.h> using namespace std; typed

【CF459D】 Pashmak and Parmida&#39;s problem [树状数组]

CF459D Pashmak and Parmida's problem 给出长度为n的序列a. f(i,j,x)表示ai..aj中x的出现次数. 求有多少对i,j满足f(1,i,ai) > f(j,n,aj).(i<j) 害挺水 就是开始计数那用的玄学vector超时了... 用 map/离散化预处理出 f(1, i, a[i]) 和 f(j, n, a[j]) 类似求逆序对,树状数组.维护 #include<bits/stdc++.h> using namespace std;

Codeforces Round #424 (Div. 2) D 思维 E set应用,树状数组

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) D. Office Keys 题意:一条直线上,有个办公室坐标 p,有 n个人在a[i],有 k把钥匙在b[i],每个人必须拿到一把钥匙,然后到办公室.问怎么安排花的时间最短. tags:还是不懂套路啊..其实多画两下图就能够感觉出来,2333 关键是要看出来,n个人拿的 n把钥匙应该是连续的. 然后,就是瞎暴力.. #include<bits/stdc++.h> usi

Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)

题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和Xor[i],表示1~i的xor和.因为num^num=0,所以Xor[r] ^ Xor[l - 1]求的是l~r之间出现奇数次的数字xor和. 那怎么求偶数次的呢,那我们可以先求l到r之间不重复出现数字的xor(比如1 1 2 求的是1 ^ 2),然后再xor以上求出的Xor[r] ^ Xor[l

Codeforces Round #629 (Div. 3) F - Make k Equal (离散化 树状数组维护前缀和)

https://codeforces.com/contest/1328/problem/F 首先把a数组处理成pair对(num,cnt),表示数字num有cnt个,然后按num升序排序离散化一下. 对于一个数x,若想使得小于x的数字都变成x,必须先把所有小于x的数变成x-1,然后再+1变成x. 同理,要使得大于x的数变成x,必须把所有大于x的数字变成x+1,然后再-1变成x. 以上是题意所要求的必须操作. 思路: 1. 用f[i]数组记录离散化后前i大的数字的总数,那么对于任意第i大数字,可以