【树状数组】CF961E Tufurama
挺巧妙的数据结构题(不过据说这是一种套路?
E. Tufurama
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!
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.
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
END
【树状数组】CF961E Tufurama的更多相关文章
- Codeforces 961E - Tufurama 树状数组
转自:https://blog.csdn.net/my_sunshine26/article/details/79831362 题目大意: i从1开始 基本思路: 完全没思路,所以上来就二分,果不其然 ...
- 树状数组 简单题 cf 961E
题目链接 : https://codeforces.com/problemset/problem/961/E One day Polycarp decided to rewatch his absol ...
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2221 Solved: 1179[Submit][Sta ...
- bzoj1878--离线+树状数组
这题在线做很麻烦,所以我们选择离线. 首先预处理出数组next[i]表示i这个位置的颜色下一次出现的位置. 然后对与每种颜色第一次出现的位置x,将a[x]++. 将每个询问按左端点排序,再从左往右扫, ...
- codeforces 597C C. Subsequences(dp+树状数组)
题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- BZOJ 3289: Mato的文件管理[莫队算法 树状数组]
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2399 Solved: 988[Submit][Status][Di ...
- 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组
E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
随机推荐
- 处理 wait millis 60009, active 50 ,maxactive 200 异常 过程
处理 wait millis 60009, active 50 ,maxactive 200 异常 过程2018年04月19日 16:48:46 守望dfdfdf 阅读数:1910 标签: druid ...
- Vue-mixins选项
Vue-mixins选项 Mixins用于: 1.已经写好了构造器,还要增加方法或者临时的活动时使用的方法,用混入能减少源代码的污染. 2.公用方法,用混入的方法可以减少代码量,实现代码重用.(使用全 ...
- weexpack 创建项目, 打包Android 和 ios
1: 首先确保 node.js版本大于6.0, 不然使用 weexpack 时会报错(部分使用es6语言,node版本太低不支持es6) 下面所有都是命令行执行的命令 2: 全局安装 weexpack ...
- xaml实现无边框窗口
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/w ...
- 创作了一个xml的替代格式
xml格式: <?xml version="1.0" encoding="GB2312"?> <Relations> <Relat ...
- NC57访问报错:java.sql.SQLException: Io 异常: Got minus one from a read call
一.报错信息 1. 前端登录界面 2. 后台应用日志 报错信息一致为: $$callid= $$thread=[Service Monitor and Runtime Enroment] $$ho ...
- docker使用centos7系统构建tomcat镜像
FROM shansongxian/centos-oraclejdk8:latest #此镜像使用centos7系统,精简jdk,只运行java程序,无法编译/构建 MAINTAINER huqian ...
- cms-详细页面2
详细页面遗留下来的部分: 1:当前位置 2.分享 3.时间格式 4.摘要 5.关键字: 解决方案: 1:当前位置:---后台拼接 2:分享:前端一段js代码 3.摘要,直接数据库查询 4.时间格式:引 ...
- 三种zigbee网络架构详解
在万物互联的背景下,zigbee网络应用越加广泛,zigbee技术具有强大的组网能力,可以形成星型.树型和网状网,三种zigbee网络结构各有优势,可以根据实际项目需要来选择合适的zigbee网络结构 ...
- 使用Window Media Player网页播放器
近段时间在做一个IETM的项目,项目需要使用WebBrower对包含avi的xml进行显示,可avi的显示总是有问题,网上找到这段在html中播放avi的代码,在Win10上表现不错,明天上班用Win ...