codeforces459D:Pashmak and Parmida's problem

Description

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.

Examples
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



正解:离散化+树状数组
解题报告:
  首先离散化之后,可以预处理一下每个元素的前驱相等元素个数和后继相等元素个数,O(NlogN)
  之后我们可以得到每个元素的两个值,前驱个数值pre[i]和后继个数值next[i],我们的任务就是查找i和j满足pre[i]>next[j] && i<j的个数。
  感觉是不是很像逆序对?直接从后往前往树状数组中插入next值(记得上界是n,处理一下0),每次查找比当前pre小的next个数,因为我们是从后往前插入的next,所以可以保证i<j

  codeforces的评测机真快,100w数据0.4S,丝毫不虚

 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long LL;
15 const int MAXN = 1000011;
16 int n,a[MAXN],u[MAXN];
17 int pre[MAXN],next[MAXN];
18 int jump1[MAXN],jump2[MAXN];
19 bool vis[MAXN];
20 int shu[MAXN],L;//树状数组维护共有多少个小于他的数
21 LL ans;
22 struct node{
23     int val,id;
24 }b[MAXN];
25 
26 inline int getint()
27 {
28        int w=0,q=0;
29        char c=getchar();
30        while((c<'0' || c>'9') && c!='-') c=getchar();
31        if (c=='-')  q=1, c=getchar();
32        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
33        return q ? -w : w;
34 }
35 
36 inline bool cmp(node q,node qq){ if(q.val==qq.val) return q.id<qq.id; return q.val<qq.val; }
37 
38 inline void add(int x,int val){
39     while(x<=n+1) {
40     shu[x]+=val;
41     x+=x&(-x);
42     }
43 }
44 
45 inline int query(int x){
46     int total=0;
47     while(x) {
48     total+=shu[x];
49     x-=x&(-x);
50     }
51     return total;
52 }
53 
54 inline void work(){
55     n=getint(); for(int i=1;i<=n;i++) u[i]=b[i].val=a[i]=getint(),b[i].id=i,jump2[i]=n+1;
56     sort(b+1,b+n+1,cmp);
57     for(int i=1;i<=n;i++) if(b[i].val==b[i-1].val) jump1[b[i].id]=b[i-1].id,jump2[b[i-1].id]=b[i].id;
58     sort(u+1,u+n+1);
59     L=unique(u+1,u+n+1)-u-1;
60     for(int i=1;i<=n;i++) a[i]=lower_bound(u+1,u+L+1,a[i])-u;
61     int x;
62     for(int i=1;i<=n;i++) {
63     if(vis[i]) continue; vis[i]=1;
64     x=i; while(x<=n) x=jump2[x],pre[x]=pre[jump1[x]]+1,vis[x]=1;
65     
66     }
67     memset(vis,0,sizeof(vis));
68     for(int i=n;i>=1;i--) {
69     if(vis[i]) continue; vis[i]=1;
70     x=i; while(x) x=jump1[x],next[x]=next[jump2[x]]+1,vis[x]=1;
71     }
72 
73     for(int i=n;i;i--) {
74     ans+=query(pre[i]);
75     add(next[i]+1,1);
76     }
77     printf("%lld",ans);
78 }
79 
80 int main()
81 {
82   work();
83   return 0;
84 }

 



 

转载于:https://www.cnblogs.com/ljh2000-jump/p/5757344.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值