hdu4417(离线操作 + 树状数组)
题意:
给定一个长度为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(离线操作 + 树状数组)的更多相关文章
- HDU3874Necklace(树状数组+离线操作)
此题的大意思说有一串珠子,每个珠子都有自己的欣赏值value,现在给你一串珠子每个的欣赏值,并给出一些询问,查询某个区间内部总欣赏值是多少,但是有一个约定就是如果这个区间内部有两个珠子的欣赏值是一样的 ...
- HDU---4417Super Mario 树状数组 离线操作
题意:给定 n个数,查询 位置L R内 小于x的数有多少个. 对于某一次查询 把所有比x小的数 ”的位置“ 都加入到树状数组中,然后sum(R)-sum(L-1)就是答案,q次查询就要离线操作了,按高 ...
- Necklace(树状数组+离线操作)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3874 Necklace Time Limit: 15000/5000 MS (Java/Others) ...
- HDU 4630 No Pain No Game 树状数组+离线操作
题意:给一串数字,每次查询[L,R]中两个数的gcd的最大值. 解法:容易知道,要使取两个数让gcd最大,这两个数最好是倍数关系,所以处理出每个数的所有倍数,两两间根据倍数关系形成一条线段,值为该数. ...
- Codeforces 369E Valera and Queries --树状数组+离线操作
题意:给一些线段,然后给m个查询,每次查询都给出一些点,问有多少条线段包含这个点集中的一个或多个点 解法:直接离线以点为基准和以线段为基准都不好处理,“正难则反”,我们试着求有多少线段是不包含某个查询 ...
- bzoj 1878 SDOI2009树状数组 离线操作
本来想写2120的,结果想起来了这个 我们先对于询问左端点排序,用树状数组存区间字母个数,对于每种字母, 第一次出现的位置记录为1,剩下的记录为0,然后记录下,每种颜色 后面第一个和他相同颜色的位置 ...
- ACM学习历程—HDU4417 Super Mario(树状数组 && 离线)
Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...
- hdu-4417 Super Mario(树状数组 + 划分树)
题目链接: Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- hdu 3333(树状数组 + 离线操作)
Turing Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- 【Kruscal最小生成树】D. Jungle Roads
https://www.bnuoj.com/v3/contest_show.php?cid=9154#problem/D [Accepted] #include<iostream> #in ...
- ubuntu samba 配置简介
Ubuntu 11.04下虚拟机Samba的共享配置详细步骤 一. Ubuntu 11.04下Samba的安装: $ sudo apt-get insall samba ...
- python学习之---- paramiko 模块
paramiko 模块 功能:提供了ssh及sftp进行远程登录服务器执行命令和上传下载文件的功能.这是一个第三方的软件包,使用之前需要安装. 1 基于用户名和密码的 sshclient 方式登录 ...
- HDU 3609 二分图多重匹配
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- CodeForces 599C Day at the Beach
预处理一下i到n的最小值. #include<cstdio> #include<cstring> #include<cmath> #include<algor ...
- [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树
游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...
- 洛谷——P2820 局域网
P2820 局域网 题目背景 某个局域网内有n(n<=100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成 ...
- 【.Net Core 学习系列】-- EF Core实践(DB First)
一.开发环境: VS2015, .Net Core 1.0.0-preview2-003156 二.准备数据: CREATE DATABASE [Blogging]; GO USE [Blogging ...
- 选带傅里叶变换(zoom-fft)
选带傅里叶变换的原理大家能够看书.大致的步骤为 移频 (将选带的中心频率移动到零频) 数字低通滤波器 (防止频率混叠) 又一次採样 (将採样的数据再次间隔採样,间隔的数据取决于分析的带宽,就是放大 ...
- Visual Studio Visual assistant注释也做拼写检查怎么办
1 打开Visual Assistant 2 在Advanced中找到Underlines,取消勾选"Underline spelling errors in comments and ...