【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)
pid=5654">【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)
xiaoxin and his watermelon candy
Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 233 Accepted Submission(s): 61
xiaoxin is very smart since he was a child. He arrange these candies in a line and at each time before eating candies, he selects three continuous watermelon candies from a specific range [L, R] to eat and the chosen triplet must satisfies:
if he chooses a triplet (ai,aj,ak)
then:
1. j=i+1,k=j+1
2. ai≤aj≤ak
Your task is to calculate how many different ways xiaoxin can choose a triplet in range [L, R]?
two triplets (a0,a1,a2)
and (b0,b1,b2)
are thought as different if and only if:
a0≠b0
or a1≠b1
or a2≠b2
T(T≤10)
which represents the number of test cases.
For each test case, the first line contains a single integer
n(1≤n≤200,000)which
represents number of watermelon candies and the following line contains
n
integer numbers which are given in the order same with xiaoxin arranged them from left to right.
The third line is an integer Q(1≤200,000)
which is the number of queries. In the following Q
lines, each line contains two space seperated integers
l,r(1≤l≤r≤n)
which represents the range [l, r].
1
5
1 2 3 4 5
3
1 3
1 4
1 5
1
2
3
pid=5648" target="_blank">5648
pid=5646" target="_blank">5646
5645题目大意:有n个糖果。从左到右列出每一个糖果的甜度
之后有Q次查询,每次查询[L,R]中三元组的个数
这个三元组要求满足为连续的三个值,然后这三个值为非递减。
问[L,R]中不反复的三元组的个数。
反复表示三元组中三个数均对影响等。
假设反复则仅仅记一次
正解为主席树………………额………………恩…………
搜到这个离线+树状数组的写法,给大家分享下
思路非常巧妙。先离线存储全部查询。
然后对查询进行排序,以右边界从小到大排序。
然后从1到n開始枚举位置pos
每到一个位置,看一下从当前往后连续的三个满不满足题目中三元组的要求,假设满足。在树状数组中1的位置+1 pos+1处-1
如今让我们先不考虑反复。
经过如上处理,对于全部右边界等于pos+2的区间,树状数组中0~L的值即为三元组个数!
由于假设满足R等于pos+2 事实上就是找全部出现过的l >= L的三元组,在遍历的过程中。每一个满足要求的三元组pos+1处-1了,事实上就是求0~L的区间和了
想想看~~
至于R 等于pos+2 因为对查询依照R排序了,所以在遍历的过程中对于每一个pos都把查询遍历到右区间pos+2就好啦
这里没有去重,关于去重。我是琢磨了好久……做法就是哈希,哈希三元组。
假设没出现过。跟上面一样,在线段树1处+1
假设出现过,须要在上次出现的位置+1处 累加上一个1
这样就能够避免反复统计了
做这道题真长记性……因为要哈希,排序必须对全部元素都进行比較。
否则会出现重叠!
这也是跟其内部实现相关。
代码例如以下:
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread() freopen("in.in","r",stdin)
#define fwrite() freopen("out.out","w",stdout) using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 10000;
const int mod = 1e9+7;
const double eps = 1e-8; int bit[233333];
int n; int Lowbit(int x)
{
return x&(-x);
} int sum(int x)
{
int ans = 0;
while(x)
{
ans += bit[x];
x -= Lowbit(x);
}
return ans;
} void add(int x,int d)
{
while(x <= n)
{
bit[x] += d;
x += Lowbit(x);
}
} struct Point
{
int l,r,id;
bool operator <(const struct Point a)const
{
return r == a.r? l == a.l? id < a.id: l < a.l: r < a.r;
}
Point(int _l = 0,int _r = 0,int _id = 0):l(_l),r(_r),id(_id){};
}; Point pt[233333];
int num[233333];
int ans[233333];
int p[233333]; int main()
{
int t,m; scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 1; i <= n; ++i)
scanf("%d",&num[i]);
scanf("%d",&m);
for(int i = 0; i < m; ++i)
{
scanf("%d%d",&pt[i].l,&pt[i].r);
pt[i].id = i;
} memset(ans,0,sizeof(ans));
memset(bit,0,sizeof(bit));
sort(pt,pt+m); map <Point,int> mp;
int j = 0;
int tp = 1;
for(int i = 1; i <= n-2; ++i)
{
if(num[i] <= num[i+1] && num[i+1] <= num[i+2])
{
if(!mp[Point(num[i],num[i+1],num[i+2])])
{
mp[Point(num[i],num[i+1],num[i+2])] = tp;
p[tp++] = 0;
}
int x = mp[Point(num[i],num[i+1],num[i+2])];
add(p[x]+1,1);
add(i+1,-1);
p[x] = i;
}
for(; j < m && pt[j].r <= i+2; ++j)
{
if(pt[j].l+2 > pt[j].r) continue;
ans[pt[j].id] = sum(pt[j].l);
}
} for(int i = 0; i < m; ++i)
printf("%d\n",ans[i]);
} return 0;
}
【HDOJ 5654】 xiaoxin 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 ...
- HDU5654xiaoxin and his watermelon candy 离线+树状数组
题意:bc 77div1 d题(中文题面),其实就是询问一个区间有多少不同的三元组,当然这个三元组要符合条件 分析(先奉上官方题解) 首先将数列中所有满足条件的三元组处理出来,数量不会超过 nn个. ...
- 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 ...
随机推荐
- A - 装箱问题
Problem Description 一个工厂生产的产品形状都是长方体,高度都是h,主要有1*1,2*2,3*3,4*4,5*5,6*6等6种.这些产品在邮寄时被包装在一个6*6*h的长方体包裹中. ...
- babel吐槽
1. .babelrc文件无法复制 每次复制项目文件,.babelrc文件都会丢失,导致项目的ES6莫名的编译失败,最可能出现的错误就是Unexpected token import错误,import ...
- inux下rz、sz的简单安装
工具/原料 在xshell或者SecureCRT这样的ssh登录软件里, 通过在Linux界面里输入rz/sz命令来上传/下载文件. 对于RHEL5, rz/sz默认没有安装所以需要手工安装. sz: ...
- spring中MessageSource的配置使用方法1
Spring定义了访问国际化信息的MessageSource接口,并提供了几个易用的实现类.首先来了解一下该接口的几个重要方法: String getMessage(String code, Ob ...
- 【CF1023C】Bracket Subsequence(模拟)
题意:给定一个正则括号序列 s ,让你在当中选择一个长度正好为 t 的子串,使得 t 恰好也是一个正则括号序列 思路:用栈模拟 #include<cstdio> #include<c ...
- sublime flatLand 主题
今天试了下感觉主题不错 记下来备忘. 1.sublime3 package control install 搜索 flatLand 2 安装完成后. 修改 Preferences 文件,通过 Sub ...
- 2017 UESTC Training for Data Structures-解题报告
题目链接:http://acm.uestc.edu.cn/#/contest/show/155 这个数据结构训练主要针对线段树,树转数组和并查集.比较适合刚入门数据结构的同学. 注意,因为后面题的代码 ...
- poj 1269 判断直线的位置关系
题目链接 题意 判断两条直线的位置关系,重合/平行/相交(求交点). 直线以其上两点的形式给出(点坐标为整点). 思路 写出直线的一般式方程(用\(gcd\)化为最简), 计算\(\begin{vma ...
- 25深入理解C指针之---传递数组
一.传递数组:将数组作为参数传入函数,或将数组作为数据当成是函数的返回值 1.定义:可以传入和传出数组 2.特征: 1).将数组作为参数传递给函数的本质是传递数组的地址,这种传递无需复制数组元素,所以 ...
- U3D层的运用
在操作 LayerMask 时常令一些初学者摸不着头脑下面简单说一下层的开关方法:1.首先引入'|'.'&'.'~'的概念与(交集):10000001 & 10000100 == 10 ...