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. c#真正判断文件类型

    //真正判断文件类型的关键函数 public static bool IsAllowedExtension2(FileUpload hifile) { if (hifile != null) { Sy ...

  2. Android开发由eclipse转Android Studio中一些常见出错问题解决方法

    1.给一个Activity添加了一个Dialog主题,结果出现了下面的问题,在eclipse却没有出错 <activity android:name=".DialogActivity& ...

  3. Annotation版本的HelloWorld

    hiberante 的 annotation历史: 在hibernate3以后,开始支持Annotation; 先有hiberante再有JPA,有了JPA标准之后,hibernate写了Annota ...

  4. SharePoint 2010 究竟需要占用多少服务器资源?

    SharePoint 安装目录(即SharePoint Root)大约 300M 磁盘空间. SharePoint Config 数据库,60M. Admin Center 数据库,100M. 默认安 ...

  5. JavaScript 获取 当前日期和三十天以前日期

    //获取当前日期 var myDate = new Date(); var nowY = myDate.getFullYear(); var nowM = myDate.getMonth()+1; v ...

  6. TP5.1:数据库的增删改查操作(基于面向对象操作)

    我们现实中对数据库的增删改查操作,都是使用模型类进行操作的(表名::),也就是面向对象操作,只有底层的代码用的是数据库操作(Db::table('表名')) 下面我将贴出模型类进行的增删改查操作,通过 ...

  7. Arduino-串口函数Serial

    串口是Arduino与其它设备进行通信的接口,我们需要很好的掌握它的使用.Arduino串口使用相关的函数共有10个(随着版本的升级,新版本加入了更多,具体请参见官网:http://www.ardui ...

  8. Selenium入门系列2 窗口大小控制

    selenium控制窗口最大化.适合手机的宽度.适合pad的宽度等尝试下实例,网站是否做了响应式布局 #coding=utf-8 # 改变浏览器窗口大小.前进后退 from selenium impo ...

  9. SVN建立分支、代码合并以及常用操作

    在项目开发的过程中,现在遇到这样一个问题: 现在是9月份,在同一个项目中我要开发A.B两个模块,A模块是11月份上线,B模块是12月份上线,但是SVN上的trunk(主干)上的代码必须是上线的. 假设 ...

  10. N76E003---看门狗

    看门狗的设置 比较简单,根据芯片手册上的说明进行设置.值得一提的是设置看门狗的寄存器是保护寄存器,所以在写寄存器的时候要解除保护 void wtd_init(void) { TA=0xAA; TA=0 ...