• 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 }


     
  • 相关阅读:
    python 下载文件保存到本地
    python 模拟udp客户端发送报文
    Block的底层代码实现
    常见的崩溃问题和类型
    NSTimer打破循环引用的几种方式
    springcloud alibaba Nacos解决OpenFeign调用失败问题
    LRU算法
    常见算法题解
    PHP无文件木马
    c++各种类型的字节数
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5757344.html
Copyright © 2020-2023  润新知