E. Tufurama

 

E. Tufurama

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

One day Polycarp decided to rewatch his absolute favourite episode of well-known TV series "Tufurama". He was pretty surprised when he got results only for season 7 episode 3 with his search query of "Watch Tufurama season 3 episode 7 online full hd free". This got Polycarp confused — what if he decides to rewatch the entire series someday and won't be able to find the right episodes to watch? Polycarp now wants to count the number of times he will be forced to search for an episode using some different method.

TV series have n seasons (numbered 1 through n), the i-th season has ai episodes (numbered 1 through ai). Polycarp thinks that if for some pair of integers x and y (x < y) exist both season x episode y and season y episode x then one of these search queries will include the wrong results. Help Polycarp to calculate the number of such pairs!

Input

The first line contains one integer n (1  ≤ n  ≤  2·105) — the number of seasons.

The second line contains n integers separated by space a1, a2, ..., an (1 ≤ ai ≤ 109) — number of episodes in each season.

Output

Print one integer — the number of pairs x and y (x < y) such that there exist both season x episode y and season y episode x.

Examples

input

Copy

5
1 2 3 4 5

output

Copy

0

input

Copy

3
8 12 7

output

Copy

3

input

Copy

3
3 2 1

output

Copy

2

Note

Possible pairs in the second example:

  1. x = 1, y = 2 (season 1 episode 2 

     season 2 episode 1);
  2. x = 2, y = 3 (season 2 episode 3 

     season 3 episode 2);
  3. x = 1, y = 3 (season 1 episode 3 

     season 3 episode 1).

In the third example:

  1. x = 1, y = 2 (season 1 episode 2 

     season 2 episode 1);
  2. x = 1, y = 3 (season 1 episode 3 

     season 3 episode 1).

 

 

 

 可持久化线段树的前缀和写法,当然本题准确来说并没有用到前缀和,却借助了其中的思想。按照下标建立可持久化线段树,每次在[1,min(i-1,a[i])]的区间里面查询 大于等于aj的数字个数,不重不漏,思维含量低。 

 

#include<bits/stdc++.h>
#define N 200005
#define int long long
#define lc tr[to].ls
#define rc tr[to].rs
#define inf 1000000000
using namespace std;
int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int n,a[N],rt[N];
struct tree
{
    int ls,rs,siz;
} tr[N*40];
int tot;
int news(int now)
{
    tr[++tot]=tr[now];
    return tot;
}
void up(int to)
{
    tr[to].siz=tr[lc].siz+tr[rc].siz;
}
int add(int now,int l,int r,int x)
{
    int to=news(now);
    if(l==r)
    {
        tr[to].siz++;
        return to;
    }
    int mid=(l+r)>>1;
    if(mid>=x)lc=add(tr[now].ls,l,mid,x);
    else rc=add(tr[now].rs,mid+1,r,x);
    up(to);
    return to;
}
int que(int nl,int nr,int l,int r,int ql,int qr)
{
    if(l>=ql&&r<=qr)return tr[nr].siz-tr[nl].siz;
    int mid=(l+r)>>1,cnt=0;
    if(mid>=ql)cnt+=que(tr[nl].ls,tr[nr].ls,l,mid,ql,qr);
    if(mid<qr)cnt+=que(tr[nl].rs,tr[nr].rs,mid+1,r,ql,qr);
    return cnt;
}
int ans=0;
signed main()
{
    n=read();
    for(int i=1; i<=n; i++)a[i]=read();
    for(int i=1; i<=n; i++)rt[i]=add(rt[i-1],1,inf,a[i]);
    for(int i=1; i<=n; i++)
    {
        int fuck=min(a[i],i-1);
        ans+=que(rt[0],rt[fuck],1,inf,i,inf);
    }
   
    cout<<ans<<"\n";
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秦三码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值