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

Problem Description
During his six grade summer vacation, xiaoxin got lots of watermelon candies from his leader when he did his internship at Tencent. Each watermelon candy has it's sweetness which denoted by an integer number.



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
 
Input
This problem has multi test cases. First line contains a single integer
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].
 
Output
For each query, print an integer which represents the number of ways xiaoxin can choose a triplet.
 
Sample Input
1
5
1 2 3 4 5
3
1 3
1 4
1 5
 
Sample Output
1
2
3
 
Source
 
Recommend
wange2014   |   We have carefully selected several similar problems for you:  5650 5649 

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(离线+树状数组)的更多相关文章

  1. HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数

    xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...

  2. HDU 5654 xiaoxin and his watermelon candy 离线树状数组

    xiaoxin and his watermelon candy Problem Description During his six grade summer vacation, xiaoxin g ...

  3. HDU5654xiaoxin and his watermelon candy 离线+树状数组

    题意:bc 77div1 d题(中文题面),其实就是询问一个区间有多少不同的三元组,当然这个三元组要符合条件 分析(先奉上官方题解) 首先将数列中所有满足条件的三元组处理出来,数量不会超过 nn个. ...

  4. POJ 3416 Crossing --离线+树状数组

    题意: 给一些平面上的点,然后给一些查询(x,y),即以(x,y)为原点建立坐标系,一个人拿走第I,III象限的点,另一个人拿II,IV象限的,点不会在任何一个查询的坐标轴上,问每次两人的点数差为多少 ...

  5. HDU 2852 KiKi's K-Number(离线+树状数组)

    题目链接 省赛训练赛上一题,貌似不难啊.当初,没做出.离线+树状数组+二分. #include <cstdio> #include <cstring> #include < ...

  6. 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) ,问在每个区间里所有 ...

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

  8. HDU3333 Turing Tree 离线树状数组

    题意:统计一段区间内不同的数的和 分析:排序查询区间,离线树状数组 #include <cstdio> #include <cmath> #include <cstrin ...

  9. 离线树状数组 hihocoder 1391 Countries

    官方题解: // 离线树状数组 hihocoder 1391 Countries #include <iostream> #include <cstdio> #include ...

随机推荐

  1. [笔记]BFS算法的python实现

    #!/usr/bin/env python # -*- coding:utf-8 -*- graph = {} graph["you"] = ["alice", ...

  2. PHP7异常处理

    try { // Code that may throw an Exception or Error. }catch (Exception $e) { } catch (Error $t) { } p ...

  3. iOS-----openGL--openGL ES iOS 入门篇4---> 离屏渲染

    http://www.cnblogs.com/CoderAlex/p/6604618.html 通常情况下,我们使用openGL将渲染好的图片绘制到屏幕上,但有时候我们不想显示处理结果,这时候就需要使 ...

  4. iOS--------对堆、栈 存储空间的理解

    Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release 栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就 ...

  5. 【Luogu】P2473奖励关(期望DP)

    题目链接 逆推期望DP.设f[i][j]为1~i-1中吃到的宝物集合为j,在i~k轮能得到的最大期望分数. 如果不吃显然f[i][j]+=f[i+1][j]/n 如果吃就是f[i][j]+=max(f ...

  6. [CODEVS1916] 负载平衡问题(最小费用最大流)

    传送门 输入所有 a[i],求出平均值 sum,每个 a[i] -= sum 那么如果 a[i] > 0,从 s 向 i 连一条容量为 a[i] 费用为 0 的有向边 如果 a[i] < ...

  7. 模拟tap事件和longTap事件

    移动端模拟tap和longTap事件,基本原理就是在touchstart和touchend事件中,计算触摸的位移和时间差,位移在一定范围内(轻微滑动),时间小于150ms为tap事件,时间大于300m ...

  8. linux监控平台搭建-内存

    linux监控平台搭建-内存 上一篇文章说的硬盘.就写一下.更加重要的东西.在手机上面是RAM.机器是memory.内存是按照字节编址.每个地址的存储单元可以存放8bit的数据.cpu 通过内存地址获 ...

  9. spring执行事务提交后进行一些逻辑操作

    在使用spring事务时,我们通常会把事务内的所有操作当成是一个原子操作.也就是当整个事务内的所有代码都执行完成后, 才会将所有的数据落实到数据库中.这样做有时也会给我们造成麻烦.比如以下场景: 根据 ...

  10. iOS8下定位问题解决

    项目是以前iOS7的,升级iOS8后,无法成功获取用户位置.后来才发现iOS8 使用定位需要在infoplist文件中加2个key,然后manager需要加一个方法,指定定位授权机制   在plist ...