挺巧妙的数据结构题(不过据说这是一种套路?

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)


看上去很可做的样子,对吧……

题目分析

基础的暴力

从1..n季,每一季都分别判断对答案的贡献。

例如对于 4 \n   ,依次检查(1,2)是否存在(2,1);(1,3)是否存在(3,1)……

首先发现a[i]对于答案的贡献最大也就是到n为止,那么读入时候先取个min(n)。

考虑一下check()是O(n)的,所以总复杂度是O(n²)的。

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用来更新那些已经 过气 没有贡献的答案。

这里「没有贡献的答案」指的是p[now].a<i的情况。说人话就是p[now]的电视剧集数太小了,已经不会再有贡献了,因此now++,判断下一个p[]是否可能会对答案有贡献。个人感觉有那么一点相似 单调队列 和 wqs二分 的情况(但是我不是非常清楚)?

为了去除这些没有贡献的季数的影响,我们只需将p[now].i位置在树状数组上-1即可。意思是说这个季数在之后的统计上都不会有贡献了。

 #include<bits/stdc++.h>
using namespace std;
long long ans;
int n,now,a[];
struct node
{
int a,i;
bool operator < (node &xx) const
{
return a < xx.a;
}
}p[];
int f[];
int read()
{
char ch = getchar();int num = ;
for (; !isdigit(ch); ch = getchar());
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
return num;
}
int lowbit(int x){return x&-x;}
void add(int x, int c){for (; x<=n+; x+=lowbit(x))f[x]+=c;}
int query(int x)
{
int ret = ;
for (; x; x-=lowbit(x))
ret += f[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 += query(a[i]);
if (a[i] >= i)ans--;
}
cout << ans / << endl;
return ;
}

另附其他做法

其他人用BIT维护也挺巧妙的(但是我觉得初看时候有点云里雾里啊)

1.Educational Codeforces Round 41 E. Tufurama (961E)  BIT做法

2.Codeforces 961E - Tufurama 【树状数组】  BIT做法

3.Codeforces - 961E Tufurama  set+BIT

4.CF 961E Tufurama  跟我一样的

END

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

  1. Codeforces 961E - Tufurama 树状数组

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组

    E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...

随机推荐

  1. Maven的学习资料收集--(七) 构建Spring项目

    在这里,使用Maven构建一个Spring项目 构建单独项目的话,其实都差不多 1. 新建一个Web项目 参考之前的博客 2.修改 pom.xml,添加Spring依赖 <project xml ...

  2. java 核心技术 读后总结

    总结 1.少用八进制,以及二进制. 那么就是直接用16进制或10进制吗?额,想当年有这样搞过,后面就uuid了. 2.>>>用0填充高位>>用符号位填充高位<< ...

  3. [技术交流ppt]babel7中preset-env的优化使用

    备注 pdf在这里

  4. Android Service创建USB HOST通信

    之前做了一个关于Android USB通信的Case,通过Android的USB总线给Zigbee供电,和板载的Zigbee(基于Zigbee的自组网)进行通信.要使用Android的USB Host ...

  5. 从零开始的全栈工程师——js篇2.6

    函数 Var 是js的关键字,用于声明变量,声明在内存模块完成,定义(=)是在执行模块完成. Var可以在内存模块提前(js代码执行前)完成所以有变量提升这个功能. 因为a没有带var,所以不存在变量 ...

  6. ps使用

    1.图片剪裁 1.按快捷键M(矩形选择工具)-> 选中要扣出的图片(按shift可正方形)->按快捷键C(剪裁工具)->双击鼠标选中区域,剪裁成功. 2.选中psd中的图标 1.按快 ...

  7. CSS实现下拉菜单的几种方法

    PS:转自https://www.cnblogs.com/yewenxiang/p/6064117.html 第一种:display:none和display:block切换 1 <!DOCTY ...

  8. ASP.NET MVC中使用窗体验证出现上下文的模型在数据库创建后发生更改,导致调试失败(一)

    在ASP.NET MVC中使用窗体验证.(首先要明白,验证逻辑是应该加在Model.View和Controller哪一个里面?由于Model的责任就是负责信息访问与商业逻辑验证的,所以我们把验证逻辑加 ...

  9. android获取https证书

    最近碰到一个问题, 有朋友问android这边能不能拿到服务器下发的证书,意思就是   自签名证书的https接口,在请求的时候,也没有添加自签名证书进信任列表,直接去发https请求,按照正常htt ...

  10. 使用Qt生成第一个窗口程序

    一.打开QtCreater,点击New Project 二.在Qt中,最常用的窗口程序为widgets控件程序,这里我们选择Qt Widgets Application 三.Qt生成的debug和re ...