题意:

给定一个长度为n的数组,有m次的查询,每次查询[a,b]区间里比H小的数有多少个?

由于n和m的取值范围为0到10的5次方,所以直接回答会超时,所以考虑先读入所有的查询操作,然后依次回答比H小的[a,b]区间里的数有多少个,

求和类似于求正序数的方法。

写法可以边插变查,也可以边查边插,边查边插简单些;

可是这道题从头wa到了尾,原因是add函数少打了等于号,扇自己一巴掌.

边插边查:

#include <iostream>
#include <cstdio>
#include <time.h>
#include <stdlib.h>
#include <cstring>
#include<algorithm>
#define maxn 110000
#define LL int
using namespace std;
struct node
{
LL value,id;
};
struct querynode
{
LL L,R,H=-,cnt;
};
node a[maxn];
querynode que[maxn];
LL c[maxn];
LL N,M;
LL ans[maxn];
void init()
{
memset(a,,sizeof(a));
memset(c,,sizeof(c));
memset(ans,,sizeof(ans));
} bool cmp1(node a,node b)
{
return a.value<b.value;
}
bool cmp2(querynode a,querynode b)
{
return a.H<b.H;
}
int inline lowbit(int x){
return x & (-x);
}
void inline add(int x){
while(x <= N){
c[x]++;
x += lowbit(x);
}
}
int inline sum(int x){
int s = ;
while(x > ){
s += c[x];
x -= lowbit(x);
}
return s;
} void solve()
{
int t=;
for(int i=;i<=N;i++)
{
if(que[t].H==-)
{
break;
}
while(que[t].H<a[i].value && que[t].H!=-)
{
ans[ que[t].cnt ]=sum(que[t].R)-sum(que[t].L-);
t++;
}
add(a[i].id);
while(a[i].value==a[i+].value && i<=N)
{
i++;
add(a[i].id);
}
while(que[t].H==a[i].value && que[t].H!=-)
{
ans[ que[t].cnt ]=sum(que[t].R)-sum(que[t].L-);
t++;
}
}
for(int i=t;i<=M;i++)
{
ans[que[i].cnt]=sum(que[i].R)-sum(que[i].L-);
}
}
int main()
{
// freopen("test.txt","r",stdin);
int t;
scanf("%d",&t);
int Case=;
for(int Case=;Case<=t;Case++)
{
scanf("%d%d",&N,&M);
init();
for(int i=;i<=N;i++)
{
scanf("%d",&a[i].value);
a[i].id=i;
}
for(int i=;i<=M;i++)
{
scanf("%d%d%d",&que[i].L,&que[i].R,&que[i].H);
que[i].L++;
que[i].R++;
que[i].cnt=i;
}
sort(a+,a+N+,cmp1);
sort(que+,que+M+,cmp2);
solve();
printf("Case %d:\n",Case);
for(int i = ; i <= M; ++i){
printf("%d\n",ans[i]);
}
} return ;
}

边查边插:

#include <iostream>
#include <cstdio>
#include <time.h>
#include <stdlib.h>
#include <cstring>
#include<algorithm>
#define maxn 110000
#define LL int
using namespace std;
struct node
{
LL value,id;
};
struct querynode
{
LL L,R,H,cnt;
};
node a[maxn];
querynode que[maxn];
LL c[maxn];
LL N,M;
LL ans[maxn];
void init()
{
memset(a,,sizeof(a));
memset(c,,sizeof(c));
memset(ans,,sizeof(ans));
for(int i=;i<maxn;i++)
{
que[i].H=-;
}
} bool cmp1(node a,node b)
{
return a.value<b.value;
}
bool cmp2(querynode a,querynode b)
{
return a.H<b.H;
}
int inline lowbit(int x){
return x & (-x);
}
void inline add(int x){
while(x <= N ){
c[x]++;
x += lowbit(x);
}
}
int inline sum(int x){
int s = ;
while(x > ){
s += c[x];
x -= lowbit(x);
}
return s;
} void solve1()
{
for(int aski = ,ditj = ; aski < M; ++aski){
while(ditj < N && que[aski].H >= a[ditj].value){
add(a[ditj].id);
ditj++;
}
ans[que[aski].cnt] = sum(que[aski].R) - sum(que[aski].L - );
}
}
int main()
{
//freopen("test.txt","r",stdin);
int t;
scanf("%d",&t);
int Case=;
for(int Case=;Case<=t;Case++)
{
scanf("%d%d",&N,&M);
init();
for(int i=;i<N;i++)
{
scanf("%d",&a[i].value);
a[i].id=i+;
}
for(int i=;i<M;i++)
{
scanf("%d%d%d",&que[i].L,&que[i].R,&que[i].H);
que[i].L++;
que[i].R++;
que[i].cnt=i+;
}
sort(a,a+N,cmp1);
sort(que,que+M,cmp2);
solve1();
printf("Case %d:\n",Case);
for(int i = ; i <= M; ++i){
printf("%d\n",ans[i]);
}
} return ;
}

hdu4417(离线操作 + 树状数组)的更多相关文章

  1. HDU3874Necklace(树状数组+离线操作)

    此题的大意思说有一串珠子,每个珠子都有自己的欣赏值value,现在给你一串珠子每个的欣赏值,并给出一些询问,查询某个区间内部总欣赏值是多少,但是有一个约定就是如果这个区间内部有两个珠子的欣赏值是一样的 ...

  2. HDU---4417Super Mario 树状数组 离线操作

    题意:给定 n个数,查询 位置L R内 小于x的数有多少个. 对于某一次查询 把所有比x小的数 ”的位置“ 都加入到树状数组中,然后sum(R)-sum(L-1)就是答案,q次查询就要离线操作了,按高 ...

  3. Necklace(树状数组+离线操作)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3874 Necklace Time Limit: 15000/5000 MS (Java/Others) ...

  4. HDU 4630 No Pain No Game 树状数组+离线操作

    题意:给一串数字,每次查询[L,R]中两个数的gcd的最大值. 解法:容易知道,要使取两个数让gcd最大,这两个数最好是倍数关系,所以处理出每个数的所有倍数,两两间根据倍数关系形成一条线段,值为该数. ...

  5. Codeforces 369E Valera and Queries --树状数组+离线操作

    题意:给一些线段,然后给m个查询,每次查询都给出一些点,问有多少条线段包含这个点集中的一个或多个点 解法:直接离线以点为基准和以线段为基准都不好处理,“正难则反”,我们试着求有多少线段是不包含某个查询 ...

  6. bzoj 1878 SDOI2009树状数组 离线操作

    本来想写2120的,结果想起来了这个 我们先对于询问左端点排序,用树状数组存区间字母个数,对于每种字母, 第一次出现的位置记录为1,剩下的记录为0,然后记录下,每种颜色 后面第一个和他相同颜色的位置 ...

  7. ACM学习历程—HDU4417 Super Mario(树状数组 && 离线)

    Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...

  8. hdu-4417 Super Mario(树状数组 + 划分树)

    题目链接: Super Mario Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Other ...

  9. hdu 3333(树状数组 + 离线操作)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. HTTP API 自动化测试从手工测试到平台的演变

    不管是 Web 系统,还是移动 APP,前后端逻辑的分离设计已经是常态化,相互之间通过 API 调用进行数据交互.在基于 API 约定的开发模式下,如何加速请求 / 响应的 API 测试,让研发人员及 ...

  2. SGU 194 无源无汇可行流求解

    题意:n个点,m条边,每条边有容量限制 l--c,每个点满足容量平衡(流入等于流出),求可行解 无源无汇可行流问题,建立以一个超级源点和超级汇点,由于原来最大流问题时候,流量下界其实为0, 所以要转化 ...

  3. delphi操作xml学习笔记 之一 入门必读

    Delphi 对XML的支持---TXMLDocument类       Delphi7 支持对XML文档的操作,可以通过TXMLDocument类来实现对XML文档的读写.可以利用TXMLDocum ...

  4. [Bzoj3131][Sdoi2013]淘金(数位dp)(优先队列)

    3131: [Sdoi2013]淘金 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 847  Solved: 423[Submit][Status][ ...

  5. maven之基础

    一.配置maven的环境 下载地址:http://maven.apache.org/download.cgi(window下载(Binary zip)的) 将maven解压,然后配置环境变量打开: 计 ...

  6. Failed to load session “ubuntu" 问题解决总结

    最近在用Ubuntu系统,但因为手欠,将unity-2d给删除了,导致总是进不了图形界面,登陆之后显示failed to load session "ubuntu“,返回之后又回到登录界面. ...

  7. android 自己定义水平和圆形progressbar 仅仅定义一些style就能够

    效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/diss ...

  8. 微信小程序之 ShoppingCart(购物车)

    1.项目目录 2.逻辑层 group.js // pages/group/group.js Page({ /** * 页面的初始数据 */ data: { goodslist: [ { id: &qu ...

  9. 微信小程序之 页面跳转 及 调用本地json的假数据调试

    一.微信小程序 跳转页面 小程序页面有2种跳转,可以在wxml页面或者js中: (1)在wxml页面中: <navigator url="../index/index"> ...

  10. hdu5399Too Simple

    //给m个函数 //其相应是自变量x属于{1,2,...n} //f(x)属于{1,2...3} //给出当中一些函数,问有多少种不同的函数集合使得 //1<=i<=n f1(f2(f3. ...