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. A - 装箱问题

    Problem Description 一个工厂生产的产品形状都是长方体,高度都是h,主要有1*1,2*2,3*3,4*4,5*5,6*6等6种.这些产品在邮寄时被包装在一个6*6*h的长方体包裹中. ...

  2. babel吐槽

    1. .babelrc文件无法复制 每次复制项目文件,.babelrc文件都会丢失,导致项目的ES6莫名的编译失败,最可能出现的错误就是Unexpected token import错误,import ...

  3. inux下rz、sz的简单安装

    工具/原料 在xshell或者SecureCRT这样的ssh登录软件里, 通过在Linux界面里输入rz/sz命令来上传/下载文件. 对于RHEL5, rz/sz默认没有安装所以需要手工安装. sz: ...

  4. spring中MessageSource的配置使用方法1

    Spring定义了访问国际化信息的MessageSource接口,并提供了几个易用的实现类.首先来了解一下该接口的几个重要方法:  String getMessage(String code, Ob ...

  5. 【CF1023C】Bracket Subsequence(模拟)

    题意:给定一个正则括号序列 s ,让你在当中选择一个长度正好为 t 的子串,使得 t 恰好也是一个正则括号序列 思路:用栈模拟 #include<cstdio> #include<c ...

  6. sublime flatLand 主题

    今天试了下感觉主题不错 记下来备忘. 1.sublime3 package control install  搜索 flatLand 2 安装完成后. 修改 Preferences 文件,通过 Sub ...

  7. 2017 UESTC Training for Data Structures-解题报告

    题目链接:http://acm.uestc.edu.cn/#/contest/show/155 这个数据结构训练主要针对线段树,树转数组和并查集.比较适合刚入门数据结构的同学. 注意,因为后面题的代码 ...

  8. poj 1269 判断直线的位置关系

    题目链接 题意 判断两条直线的位置关系,重合/平行/相交(求交点). 直线以其上两点的形式给出(点坐标为整点). 思路 写出直线的一般式方程(用\(gcd\)化为最简), 计算\(\begin{vma ...

  9. 25深入理解C指针之---传递数组

    一.传递数组:将数组作为参数传入函数,或将数组作为数据当成是函数的返回值 1.定义:可以传入和传出数组 2.特征: 1).将数组作为参数传递给函数的本质是传递数组的地址,这种传递无需复制数组元素,所以 ...

  10. U3D层的运用

    在操作 LayerMask 时常令一些初学者摸不着头脑下面简单说一下层的开关方法:1.首先引入'|'.'&'.'~'的概念与(交集):10000001 & 10000100 == 10 ...