HDU5654xiaoxin and his watermelon candy 离线+树状数组
题意:bc 77div1 d题(中文题面),其实就是询问一个区间有多少不同的三元组,当然这个三元组要符合条件
分析(先奉上官方题解)
首先将数列中所有满足条件的三元组处理出来,数量不会超过 nn个。
设 pre[i] 为第 i 个三元组前一次出现的位置,如果在前面没有出现过则设为0,对于不合法的三元组,pre[i]设为 n。
这样对于一个查询 [L, R], 我们只不需要计算出 在这个区间内有多少个三元组的 pre 值是小于 L 的。
到这里,就可以使用可持久化线段树来计算了。
-------------------------------------------------------------华丽的分割线
然后蒟蒻表示不会这种在线的主席树做法,主席树据说很好,马上去学习
然后介绍本蒟蒻的离线做法,其实都是套路,就是求一个区间包含了,多少个小区间(即三元组)
首先和题解一样,找到符合条件的三元组,记录它的序号id,这个三元组的每个元素,他的右边界
然后按照三元组排序,以及他的id,这样处理每个三元组的pre,即在他左边,与他相同的三元组的id
然后恢复下顺序
然后就是离线的套路,把查询区间按照右端点排序,更新所有三元组右边界小于他的左端点,然后区间求和,就是答案
但是这个题有一个点,要避免查询重复,所以在当前查询的时候,要保证没有重复,所以更新三元组时,要把他的pre删掉(因为相同)
这样对于重复的三元组,只保留最靠近当前查询区间右端的
代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=2e5+;
const int INF=0x3f3f3f3f;
struct Node{
int a,b,c,id,pre,r;
bool operator==(const Node &rhs)const{
if(a==rhs.a&&b==rhs.b&&c==rhs.c)
return ;
return ;
}
}o[N];
int n,T,q;
bool cmp1(Node x,Node y){
if(x.a!=y.a)
return x.a<y.a;
if(x.b!=y.b)
return x.b<y.b;
if(x.c!=y.c)
return x.c<y.c;
return x.id<y.id;
}
bool cmp2(Node x,Node y){
return x.id<y.id;
}
int d[N],ans[N];
struct Q{
int l,r,id;
bool operator<(const Q &rhs)const{
return r<rhs.r;
}
}p[N];
int bit[N];
void add(int x,int t){
for(int i=x;i<=n;i+=i&(-i))
bit[i]+=t;
}
int get(int x){
int ans=;
for(int i=x;i>;i-=i&(-i))
ans+=bit[i];
return ans;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
int cnt=;
for(int i=;i<=n;++i){
scanf("%d",&d[i]);
if(i<=)continue;
if(d[i]>=d[i-]&&d[i-]>=d[i-]){
++cnt;
o[cnt].a=d[i-],o[cnt].b=d[i-];
o[cnt].c=d[i],o[cnt].pre=-;
o[cnt].r=i,o[cnt].id=cnt;
}
}
sort(o+,o++cnt,cmp1);
for(int i=;i<=n;++i){
if(o[i]==o[i-]){
o[i].pre=o[i-].id;
}
}
sort(o+,o++cnt,cmp2);
scanf("%d",&q);
for(int i=;i<=q;++i){
scanf("%d%d",&p[i].l,&p[i].r);
p[i].id=i;
}
sort(p+,p++q);
int pos=;
memset(bit,,sizeof(bit));
for(int i=;i<=q;++i){
for(;pos<=cnt&&o[pos].r<=p[i].r;++pos){
int pre=o[pos].pre;
if(pre!=-)
add(o[pre].r-,-);
add(o[pos].r-,);
}
ans[p[i].id]=get(p[i].r)-get(p[i].l-);
}
for(int i=;i<=q;++i)
printf("%d\n",ans[i]);
}
return ;
}
HDU5654xiaoxin and his watermelon candy 离线+树状数组的更多相关文章
- HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数
xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...
- HDU 5654 xiaoxin and his watermelon candy 离线树状数组
xiaoxin and his watermelon candy Problem Description During his six grade summer vacation, xiaoxin g ...
- 【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)
pid=5654">[HDOJ 5654] xiaoxin and his watermelon candy(离线+树状数组) xiaoxin and his watermelon c ...
- POJ 3416 Crossing --离线+树状数组
题意: 给一些平面上的点,然后给一些查询(x,y),即以(x,y)为原点建立坐标系,一个人拿走第I,III象限的点,另一个人拿II,IV象限的,点不会在任何一个查询的坐标轴上,问每次两人的点数差为多少 ...
- HDU 2852 KiKi's K-Number(离线+树状数组)
题目链接 省赛训练赛上一题,貌似不难啊.当初,没做出.离线+树状数组+二分. #include <cstdio> #include <cstring> #include < ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组
题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)
转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...
- HDU3333 Turing Tree 离线树状数组
题意:统计一段区间内不同的数的和 分析:排序查询区间,离线树状数组 #include <cstdio> #include <cmath> #include <cstrin ...
- 离线树状数组 hihocoder 1391 Countries
官方题解: // 离线树状数组 hihocoder 1391 Countries #include <iostream> #include <cstdio> #include ...
随机推荐
- C++ const修饰函数、函数参数、函数返回值
const修饰函数 在类中将成员函数修饰为const表明在该函数体内,不能修改对象的数据成员而且不能调用非const函数.为什么不能调用非const函数?因为非const函数可能修改数据成员,cons ...
- PHP中0、空、null和false的总结
php中很多人还不懂php中 0 , '' , null 和 false 之间的区别,这些区别有时会影响到数据判断的正确性和安全性,给程序的测试运行造成很多麻烦.另外在面试题中也会遇到这些问题,如下: ...
- linux正则表达式之-基础正则表达式(基于grep)
linux正则表达式: 简单的说,正则表达式就是为处理大量的字符串而定义的一套规则和方法,如:假设@代表123456,!代表abcde.通过定义的这些特殊符号的铺助,系统管理员就可以快速的过滤,替换或 ...
- 不相交集合ADT
不相交集合数据结构保持一组不相交的动态集合S={S1,S2,...,SK},每个集合通过一个代表来识别,代表即集合中的某个成员. 如果x表示一个对象,不相交集合支持以下操作: MAKE-SET(x): ...
- jcom2在win7 X86上操作Excel
浅谈Java中利用JCOM实现仿Excel编程 在JAVA中使用JCOM和JXL注意要点: (1)在你的lib下要有jdom-1.0.jar,jxl-2.5.5.jar,jcom-2.2.4.ja ...
- iOS 中SQLite数据库操作
在iOS中实现SQLite数据库的操作:1.导入框架(libsqlite3.0.tbd) 2.导入头文件<sqlite3.h> 3.实现数据的增删改查 实现简单 SQLite数据库操作 的 ...
- Linux查看用户和组命令
在Linux系统里,我们会经常用Linux查看用户的命令,在这里我们一些命令进行了总结,总共有7个,并做了详细的解释,以便让大家更深入的理解,接下来让我们一起来看看这些命令和具体应用. 一.Linux ...
- mysql中实现行号,oracle中的rowid
mysql中实现行号需要用到MYSQL的变量,因为MySql木有rownumber. MYSQL中变量定义可以用 set @var=0 或 set @var:=0 可以用=或:=都可以,但是如果变量用 ...
- HDU3368+枚举
题意看不懂的直接看百度百科对黑白棋的解释... 做法:分情况讨论,一共8个方向. /* 搜索 */ #include<stdio.h> #include<string.h> ; ...
- android 为activity添加optionMenu选项菜单
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android: ...