CF961E Tufurama

题意翻译

题目描述

有一天Polycarp决定重看他最喜爱的电视剧《Tufurama》。当他搜索“在线全高清免费观看Tufurama第3季第7集”却只得到第7季第3集的结果时,他很惊讶。这让Polycarp感到疑惑——如果有天他决定重看整个系列却无法找到正确的剧集观看,那该怎么办呢?Polycarp现在想统计一下他被迫用不同方案搜索同一剧集的次数。

电视连续剧有n 季(从1 到n 编号),第i 季有ai​ 集(从1 到ai​ 编号)。Polycarp认为如果有一对x 和y (x<y),使第x 季第y 集、第y 季第x 集存在,那么其中一个搜索就会包含错误的内容。请帮助Polycarp统计这样的数对的数量吧!

输入输出格式

输入格式

第一行,一个整数n(1≤n≤2⋅105) ,表示季数。

第二行,n 个用空格隔开的整数a1​,a2​,...,an​(1≤ai​≤109) ,表示每一季的集数。

输出格式

只有一行,一个整数,表示x 和y (x<y ),使第x 季第y 集、第y 季第x 集存在的数对的数量。

说明

在样例2中可能的对数:

  1. x=1,y=2 (第1季第2集第2季第1集)
  2. x=2,y=3 (第2季第3集第3季第2集)
  3. x=1,y=3 (第1季第3集第3季第1集)

在样例3中:

  1. x=1,y=2 (第1季第2集第2季第1集)
  2. x=1,y=3 (第1季第3集第3季第1集)

感谢@月见之兔 提供的翻译

题目描述

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 xepisode y and season yepisode x then one of these search queries will include the wrong results. Help Polycarp to calculate the number of such pairs!

输入输出格式

输入格式:

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.

输出格式:

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 .

输入输出样例

输入样例#1: 复制

5
1 2 3 4 5
输出样例#1: 复制

0
输入样例#2: 复制

3
8 12 7
输出样例#2: 复制

3
输入样例#3: 复制

3
3 2 1
输出样例#3: 复制

2

说明

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).

Solution

哭哭 多久没遇到这种不用看题解就能a掉的紫题了QAQ

一句话题意:求有多少对$<i,j>$,满足$a[i]>=j,a[j]>=i,i<j$

然后把关系再理一下,就变成了,对于每一个$i$,求在区间$[i+1,min(n,a[i])]$内有多少个$j$满足$a[j]>=i$

然后就是主席树叻~

倒着遍历维护每一个版本,查询区间就是用区间两个端点的版本满足条件的个数相减得到答案。

要离散化~

Code

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std; const int N = ; int n, a[N], b[ * N]; struct Node {
Node *ls, *rs;
int pos, val;
void update() {
val = ls -> val + rs -> val;
}
} pool[*N], *root[N], *tail = pool, *zero; Node *newnode() {
Node *nd = ++ tail;
nd -> ls = zero;
nd -> rs = zero;
nd -> pos = ;
nd -> val = ;
return nd;
} Node *build(int l, int r) {
Node *nd = newnode();
if(l == r) return nd;
int mid = (l + r) >> ;
nd -> ls = build(l, mid);
nd -> rs = build(mid + , r);
nd -> update();
return nd;
} int query(Node *nd, int l, int r, int L, int R) {
if(l >= L && r <= R) return nd -> val;
int ans = ; int mid = (l + r) >> ;
if(L <= mid) ans += query(nd -> ls, l, mid, L, R);
if(R > mid) ans += query(nd -> rs, mid + , r, L, R);
return ans;
} Node *insert(Node *nd, int l, int r, int pos) {
Node *nnd = newnode();
if(l == r) {
nnd -> val = nd -> val + ; return nnd;
}
int mid = (l + r) >> ;
if(pos <= mid) {
nnd -> rs = nd -> rs;
nnd -> ls = insert(nd -> ls, l, mid, pos);
} else {
nnd -> ls = nd -> ls;
nnd -> rs = insert(nd -> rs, mid + , r, pos);
}
nnd -> update();
return nnd;
} int main() {
zero = ++ tail;
zero -> ls = zero; zero -> rs = zero; zero -> pos = ; zero -> val = ;
scanf("%d", &n);
int t = ;
for(int i = ; i <= n; i ++) {
scanf("%d", &a[i]);
b[++ t] = a[i]; b[++ t] = i;
}
sort(b + , b + + t);
int m = unique(b + , b + + t) - b - ;
root[n + ] = build(, m);
long long ans = ;
for(int i = n; i >= ; i --) {
int pos = lower_bound(b + , b + + m, a[i]) - b;
int posi = lower_bound(b + , b + + m, i) - b;
int R = min(n, pos);
root[i] = insert(root[i + ], , m, pos);
if(R < i) continue;
int tmp1 = query(root[i + ], , m, posi, m);
int tmp2 = query(root[R + ], , m, posi, m);
ans += tmp1 - tmp2;
}
printf("%I64d", ans);
}

CF961E Tufurama【主席树】的更多相关文章

  1. CF961E Tufurama 主席树

    对原问题进行转化 考虑对每个$i$,询问在$j \in [i + 1, a[i]]$中满足$a[j] \geqslant i$的个数 这样子可以做到不重不漏 个数满足差分的性质,使用主席树来维护即可 ...

  2. 2018.12.05 codeforces 961E. Tufurama(主席树)

    传送门 一眼主席树sbsbsb题(%%%树状数组大佬们). 简化题意:求满足x<y,y≤ax,x≤ayx<y,y\le a_x,x\le a_yx<y,y≤ax​,x≤ay​的(x, ...

  3. 【树状数组】CF961E Tufurama

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

  4. EC Round 41 (Rated for Div. 2)主席树 E. Tufurama

    简单分析一下,对于x<y,求a[x]>=y 同时a[y]>=x 再简化一下,求1-a[y]区间内大于>=y的个数...主席树牛逼 #include<iostream> ...

  5. [CF961E] Tufurama

    Description: 有一天Polycarp决定重看他最喜爱的电视剧<Tufurama>.当他搜索"在线全高清免费观看Tufurama第3季第7集"却只得到第7季第 ...

  6. bzoj3207--Hash+主席树

    题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...

  7. bzoj1901--树状数组套主席树

    树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...

  8. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  9. BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 3522  Solved: 1041[Submi ...

随机推荐

  1. 【navicat112_premium】navicat112_premium数据库连接工具安装过程

    此工具及其方便,可以连接mysql.oracle.sqlserver登数据库... 1.下载安装包Navicat Premium_11.2.7简体中文版.rar 下载地址:http://qiaoliq ...

  2. Servlet笔记6--Servlet程序改进

    第一步改进,GenericServlet: 我们目前所有放入Servlet类直接实现了javax.servlet.Servlet接口,但是这个接口中有很多方法是目前不需要的,我们可能只需要编写serv ...

  3. 将网址url中的参数转化为JSON格式

    网上方法很多,各种奇技淫巧,这里贴上一种较为正常的思路. 主要利用split对获取的字符串不断进行分割,最后获得所需要的格式. 代码如下 <!DOCTYPE html> <html ...

  4. C 之回调函数

    软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用.同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用:回调是一种双向调用模式,也就是 ...

  5. 为什么我们不要.NET程序员(读后有点想法,所以转来了) 注:本文来自CSDN

    也许你已经知道了,我们正在招聘最优秀的程序员.不错,每个人都这样说.但是我们的程序员能打败你们的——任何时候.比如,米奇虽然只有5英尺高,但他是一个有相当实力的击剑手.维托尔德以前是一个6’3″的职业 ...

  6. idea中使用tomcat 方式启动spring boot项目

    Spring boot 的main 入口启动方式相信都会用,直接运行main直接就启动了,但是往往这种方式并不是最佳的启动方式,比如运维的层面更希望调整tomcat的调优参数,而只使用嵌入启动方式很难 ...

  7. linux用户权限 -> 系统基本权限

    比如rwxr-xr-x linux中正是这9个权限位来控制文件属主(User).属组(Group).其他用户(Other)基础权限. 用户对资源来说, 有三种角色 User(u): 属主用户(文件所有 ...

  8. window.onload绑定多个事件 —— 两种解决方案

    前言 有些函数,必须在网页加载完毕后执行.比如:涉及DOM操作的. 网页加载完毕时会触发一个onload事件,将函数绑定到这个事件上即可. window.onload = myFunction; 问题 ...

  9. 浅谈js设计模式之单例模式

    单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如线程池.全局缓存.浏览器中的 window 对象等.在 JavaS ...

  10. .NET异步多线程,Thread,ThreadPool,Task,Parallel,异常处理,线程取消

    今天记录一下异步多线程的进阶历史,以及简单的使用方法 主要还是以Task,Parallel为主,毕竟用的比较多的现在就是这些了,再往前去的,除非是老项目,不然真的应该是挺少了,大概有个概念,就当了解一 ...