E. Tufurama

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·10^5) — the number of seasons.

The second line contains n integers separated by space a1, a2, ..., an (1 ≤ ai ≤ 10^9) — 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.

题意:

有一部电视剧有n季,每一季有ai集。定义二元组(i,j):存在第i季有第j集。求(i,j)与(j,i)同时合法(i<j)的对数。

真实题意就是:求<i,j>对数,使得a[i]≥j,a[j]≥i并且(i<j)


BIT做法

像很多其他题一样,对于这样的、关于元素大小关系之间的限制的题目,先排个序总是能够解决个一维限制掉去的。

我们使用一个结构体node x,x.i表示季数;x.a表示该季的集数。首先对x.a排序。那么就变成这个样子:

p[].a(j)  3  5  1  2
p[].i(i)  1  2  3  4
  |
  |
p[].a(j)  1  2  3  4 (取min之后)
p[].i(i)  3  4  1  2

先考虑每次的统计,那么只要ans+=query(a[i])就可以了。意思就是说ans加上1..a[i]季的贡献(其中每一季的贡献要么是0要么是1,但是由于之后会有修改,所以我们用BIT维护)

now用来更新那些已经 过气 没有贡献的答案,这里「没有贡献的答案」指的是p[now].a<i的情况,就是p[now]的电视剧集数太小了,已经不会再有贡献了,由于p[i].a是单增的,因此now++,扫一遍即可。

代码:

 //#include"bits/stdc++.h"
#include<sstream>
#include<iomanip>
#include"cstdio"
#include"map"
#include"set"
#include"cmath"
#include"queue"
#include"vector"
#include"string"
#include"cstring"
#include"time.h"
#include"iostream"
#include"stdlib.h"
#include"algorithm" #define db double
#define ll long long
#define vec vector<ll>
#define mt vector<vec>
#define ci(x) scanf("%d",&x)
#define cd(x) scanf("%lf",&x)
#define cl(x) scanf("%lld",&x)
#define pi(x) printf("%d\n",x)
#define pd(x) printf("%f\n",x)
#define pl(x) printf("%lld\n",x)
//#define rep(i, x, y) for(int i=x;i<=y;i++)
#define rep(i, n) for(int i=0;i<n;i++)
const int N = 1e6 + ;
const int mod = 1e9 + ;
const int MOD = mod - ;
const int inf = 0x3f3f3f3f;
const db PI = acos(-1.0);
const db eps = 1e-;
using namespace std;
ll ans;
int n, now, a[N],bit[N];
struct node {
int a, i;
bool operator<(node &xx) const {
return a < xx.a;
}
} p[N];
int read() {
char ch = getchar();
int ret = ;
for (; !isdigit(ch); ch = getchar());
for (; isdigit(ch); ch = getchar())
ret = (ret << ) + (ret << ) + ch - ;
return ret;
}
void add(int x, int c) { for (; x <= n + ; x += x & -x)bit[x] += c; }
int sum(int x) {
int ret = ;
for (; x; x -= x & -x)
ret += bit[x];
return ret;
}
int main() {
n = read();
now = ;
for (int i = ; i <= n; i++)
a[i] = min(read(), n), p[i].a = a[i], p[i].i = i, add(i, );
sort(p + , p + n + );
for (int i = ; i <= n; i++) {
while (now <= n && p[now].a < i)add(p[now++].i, -);//去掉无贡献的值
ans += sum(a[i]);
if (a[i] >= i) ans--;//(i,j) i=j的情况去掉
}
cout << ans / << endl;
return ;
}

CF961E Tufurama 树状数组的更多相关文章

  1. Codeforces 961E - Tufurama 树状数组

    转自:https://blog.csdn.net/my_sunshine26/article/details/79831362 题目大意: i从1开始 基本思路: 完全没思路,所以上来就二分,果不其然 ...

  2. 【树状数组】CF961E Tufurama

    挺巧妙的数据结构题(不过据说这是一种套路? E. Tufurama One day Polycarp decided to rewatch his absolute favourite episode ...

  3. 树状数组 简单题 cf 961E

    题目链接 : https://codeforces.com/problemset/problem/961/E One day Polycarp decided to rewatch his absol ...

  4. BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2221  Solved: 1179[Submit][Sta ...

  5. bzoj1878--离线+树状数组

    这题在线做很麻烦,所以我们选择离线. 首先预处理出数组next[i]表示i这个位置的颜色下一次出现的位置. 然后对与每种颜色第一次出现的位置x,将a[x]++. 将每个询问按左端点排序,再从左往右扫, ...

  6. codeforces 597C C. Subsequences(dp+树状数组)

    题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...

  7. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  8. BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1399  Solved: 694[Submit][Status] ...

  9. BZOJ 3289: Mato的文件管理[莫队算法 树状数组]

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2399  Solved: 988[Submit][Status][Di ...

随机推荐

  1. Postman工具——下载与安装(转)

    https://blog.csdn.net/water_0815/article/details/53263643 今天给大家分享一款工具,好的工具能够让开发更高效,有时能成倍地提高.接下来会分几篇来 ...

  2. iOS - The identity used to sign the executable is no longer valid

    ①.首先在xcode中的Build Settings中看有没有设置: ②.账号是不是多个人在用,个人开发者的账号只能绑定一台电脑,当另外一台电脑绑定了话,你的电脑就失效了.你确认下是不是这个原因造成的 ...

  3. Java Knowledge series 1

    Programming language evolves always along with Compiler's evolvement JVM as Additional Indirection I ...

  4. [垂直化搜索引擎]lucene简介及使用

    摘自:大型分布式网站架构-设计与实践

  5. sharepoint2010的几个类型字段赋值和取值的方法

    1.日期类型查询,需要转换,方法如下: //转换时间 string startdate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(Date ...

  6. Spring Cloud学习路线

    学习本学习路线学习完,大家将会对微服务.Spring Cloud.Docker.Kubernetes有一个系统.全面的认识.通过学习,将能掌握相关的知识体系,并能够投入到项目实战中去. 本学习路线采用 ...

  7. 为什么要使用TLSv1.2和System SSL?

    FTP 和 Telnet 正是核心联网应用程序的两个示例.为 System SSL 编程接口编码的供应商应用程序可以通过更改代码来利用这些新支持. 这是安全套接层 (SSL) 协议的最新版本,也是最为 ...

  8. TP5.1:实现分页

    前提: (1)为了让分页变得更加好看,我的案例加载了bootstrap和jq的文件,具体操作请参考:http://www.cnblogs.com/finalanddistance/p/9033916. ...

  9. 使用g++ 编译C++程序

    在命令行下,编译C++程序 g++ main.cpp -o main.exe

  10. 【js基础修炼之路】- 手把手教你实现bind

    手写bind前我们先回顾一下bind有哪些特性,以便更好的理解bind和实现bind. bind的特性 var obj = { a: 100, say(one, two) { console.log( ...