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. PHP的发展史,功能与特点

    web1.0时代:所有的代码都是在浏览器端执行的静态脚本,用户请求的也都是服务器上事先已经存在的静态网页,用户和服务器之间不能进行任何的交互!(不需要数据库的支持) web2.0时代:用户和服务器之间 ...

  2. HDU——1058Humble Numbers(找规律)

    Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  3. BZOJ-1798 维护序列

    线段树.支持区间加.区间乘.区间查询和. 标记下移还有取模要注意. var n,p,q,i,s,t:longint; a:int64; num,n1,n2,n3:array[0..500000] of ...

  4. yield的概念及使用姿势

    概念: 当调用Thread.yield方法时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示. 代码演示: public class YieldDemo impl ...

  5. javaweb学习总结(十八)——JSP属性范围(转)

    所谓的属性范围就是一个属性设置之后,可以经过多少个其他页面后仍然可以访问的保存范围. 一.JSP属性范围 JSP中提供了四种属性范围,四种属性范围分别指以下四种: 当前页:一个属性只能在一个页面中取得 ...

  6. css3 boxing-sizing属性

    boxing-sizing: 1.content-box 计算宽度不包含padding和border宽度 2.border-box border和padding计算入width之内 3.padding ...

  7. Oracle Dual 表详解

    1.DUAL表的用途Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的Select语句块中--查看当前连接用户SQL> select user from dua ...

  8. ASP 500错误解决方法

    最有效的解决方法: 经  c:\windows\temp 目录增加everyone写权限. 环境: windows2008

  9. 关于django rest framework里token auth的实现及答疑

    http://stackoverflow.com/questions/14838128/django-rest-framework-token-authentication ============= ...

  10. 本地测试IIS,Post调用接口

    最近在学习三种调用接口方式,POST,Socket,Webserivce,今天刚写完POST方式所以就分享下,欢迎高手指点. public string strResult = "" ...