HDU 4638 Group (线段树 | 树状数组 + 离线处理)
Group
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 208 Accepted Submission(s): 122
For each case first line is n, m(1<=n ,m<=100000) indicate there are n men and m query.
Then a line have n number indicate the ID of men from left to right.
Next m line each line has two number L,R(1<=L<=R<=n),mean we want to know the answer of [L,R].
5 2
3 1 2 5 4
1 5
2 4
2
(转)思路:显然,我们要使得value最大,就要尽量将连续的ID分在一组,所以问题转化为求一个区间中连续ID区间的个数。我们从左往右扫描,依次考虑右端点为i的询问,设dp[l]为区间[l,i]的连续区间个数,po[i]为i出现的位置,若还未出现,则为0,设我们当前考虑的右端点为a[i],首先我们假设a[i]不能和区间[1,i-1]中的任何一个数分到一组,则我们要将dp[1]到dp[i-1]全部加1,然后考虑po[a[i]+1]是否不为0,若不为0则说明a[i]-1已经在前面出现,则我们需要将dp[1]到dp[po[a[i]+1]]全部减一个1,因为a[i]可以和a[i]+1分为一组,则我们之前加的1是多余的。对于a[i]-1的情况同理。以上操作可以由线段树或者树状数组什么的实现,然后再将询问按照右端点从小到大排序,离线处理即可,以下是代码实现
线段树:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int N=; #define L(rt) (rt<<1)
#define R(rt) (rt<<1|1) struct Tree{
int l,r;
int num; //num记录(l,r)区间内的组数
}tree[N<<]; struct node{
int l,r;
int id;
}f[N]; int cmp(node a,node b){
return a.r<b.r;
} int a[N],loc[N],res[N]; void build(int L,int R,int rt){
tree[rt].l=L;
tree[rt].r=R;
tree[rt].num=;
if(tree[rt].l==tree[rt].r)
return ;
int mid=(L+R)>>;
build(L,mid,L(rt));
build(mid+,R,R(rt));
} void update(int L,int R,int val,int rt){
if(tree[rt].l==L && tree[rt].r==R){
tree[rt].num+=val;
return ;
}
int mid=(tree[rt].l+tree[rt].r)>>;
if(R<=mid)
update(L,R,val,L(rt));
else if(L>=mid+)
update(L,R,val,R(rt));
else{
update(L,mid,val,L(rt));
update(mid+,R,val,R(rt));
}
tree[rt].num=tree[L(rt)].num+tree[R(rt)].num;
} int query(int L,int R,int rt){
if(tree[rt].l==L && tree[rt].r==R)
return tree[rt].num;
int mid=(tree[rt].l+tree[rt].r)>>;
if(R<=mid)
return query(L,R,L(rt));
else if(L>=mid+)
return query(L,R,R(rt));
else{
int a=query(L,mid,L(rt));
int b=query(mid+,R,R(rt));
return a+b;
}
} int main(){ //freopen("input.txt","r",stdin); int t,n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
loc[a[i]]=i;
}
for(int i=;i<=m;i++){
scanf("%d%d",&f[i].l,&f[i].r);
f[i].id=i;
}
sort(f+,f+m+,cmp); //将查找区间以右右区间递增排序,方便在更改线段树的时候查找,不会漏掉
build(,n,);
int i,j=;
for(i=;i<=n;i++){
update(i,i,,); //每次新进的一位数,假设独立,所有已i结尾的区间都+1
if(a[i]<n && loc[a[i]+]<i) //每次删除掉之前加入的与a[i]相邻的数,因为它们在一组里
update(loc[a[i]+],loc[a[i]+],-,);
if(a[i]> && loc[a[i]-]<i)
update(loc[a[i]-],loc[a[i]-],-,);
while(j<=m && f[j].r==i){
res[f[j].id]=query(f[j].l,f[j].r,);
j++;
}
}
for(i=;i<=m;i++)
printf("%d\n",res[i]);
}
return ;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int N=; int n,m;
int arr[N],a[N],loc[N],res[N]; struct node{
int l,r;
int id;
}f[N]; int cmp(node a,node b){
return a.r<b.r;
} int lowbit(int x){
return x&(-x);
} void update(int i,int val){
while(i<=n){
arr[i]+=val;
i+=lowbit(i);
}
} int sum(int i){
int ans=;
while(i>){
ans+=arr[i];
i-=lowbit(i);
}
return ans;
} int main(){ //freopen("input.txt","r",stdin); int t; //刚开在这里使用 int t,n,m; 这里的局部变量影响了在main函数外面定义的全局变量n(默认值为0),导致我无奈了。。。。。
scanf("%d",&t);
while(t--){ scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
loc[a[i]]=i;
}
for(int i=;i<=m;i++){
scanf("%d%d",&f[i].l,&f[i].r);
f[i].id=i;
}
sort(f+,f+m+,cmp); //将查找区间以右右区间递增排序,方便在更改线段树的时候查找,不会漏掉
memset(arr,,sizeof(arr));
int i,j=; for(i=;i<=n;i++){
update(i,); //每次新进的一位数,假设独立,所有已i结尾的区间都+1
if(a[i]<n && loc[a[i]+]<i) //每次删除掉之前加入的与a[i]相邻的数,因为它们在一组里
update(loc[a[i]+],-);
if(a[i]> && loc[a[i]-]<i)
update(loc[a[i]-],-);
while(j<=m && f[j].r==i){
res[f[j].id]=sum(f[j].r)-sum(f[j].l-);
j++;
}
}
for(i=;i<=m;i++)
printf("%d\n",res[i]);
}
return ;
}
HDU 4638 Group (线段树 | 树状数组 + 离线处理)的更多相关文章
- hdu 5057 Argestes and Sequence (数状数组+离线处理)
题意: 给N个数.a[1]....a[N]. M种操作: S X Y:令a[X]=Y Q L R D P:查询a[L]...a[R]中满足第D位上数字为P的数的个数 数据范围: 1<=T< ...
- Necklace HDU - 3874 (线段树/树状数组 + 离线处理)
Necklace HDU - 3874 Mery has a beautiful necklace. The necklace is made up of N magic balls. Each b ...
- 2016 Multi-University Training Contest 5 1012 World is Exploding 树状数组+离线化
http://acm.hdu.edu.cn/showproblem.php?pid=5792 1012 World is Exploding 题意:选四个数,满足a<b and A[a]< ...
- SPOJ DQUERY树状数组离线or主席树
D-query Time Limit: 227MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submit Status ...
- D-query SPOJ 树状数组+离线
D-query SPOJ 树状数组+离线/莫队算法 题意 有一串正数,求一定区间中有多少个不同的数 解题思路--树状数组 说明一下,树状数组开始全部是零. 首先,我们存下所有需要查询的区间,然后根据右 ...
- HDU 4638 Group ★(树状数组)
题意 询问一段区间里的数能组成多少段连续的数. 思路 先考虑从左往右一个数一个数添加,考虑当前添加了i - 1个数的答案是x,那么可以看出添加完i个数后的答案是根据a[i]-1和a[i]+1是否已经添 ...
- HDU 4638 Group 【树状数组,分块乱搞(莫队算法?)】
根据题目意思,很容易得出,一个区间里面连续的段数即为最少的group数. 题解上面给的是用树状数组维护的. 询问一个区间的时候,可以一个一个的向里面添加,只需要判断a[i]-1 和 a[i]+1是否已 ...
- HDU 4638 Group (2013多校4 1007 离线处理+树状数组)
Group Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- HDU 4638 Group 树状数组 + 思路
实际上就是问这个区间编号连续的段的个数,假如一个编号连续的段有(a+b)个人,我把他们分在同一组能得到的分值为(a+b)^2,而把他们分成人数为a和b的两组的话,得到的分值就是a^2+b^2,显然(a ...
随机推荐
- Java-Shiro(一):简介
简介 Apache Shiro是Java的一个安全权限框架. Shiro可以非常容易的开发出足够好的额应用,其不仅可以用在JavaSE环境,也可以用在Java SE环境. Shiro可以完成:认证.授 ...
- [Canvas]人物型英雄出现(前作仅为箭头)
源码点此下载,用浏览器打开index.html观看. 代码: <!DOCTYPE html> <html lang="utf-8"> <meta ht ...
- CheeseZH: Stanford University: Machine Learning Ex5:Regularized Linear Regression and Bias v.s. Variance
源码:https://github.com/cheesezhe/Coursera-Machine-Learning-Exercise/tree/master/ex5 Introduction: In ...
- VMware虛擬化技術實作問答
http://www.netadmin.com.tw/article_content.aspx?sn=1202130002&ns=1203280001&jump=3 Q4:啟用VMwa ...
- SHELL 循环获取日期以及FOR使用
;i<=;i++)); do PYTHONPATH=lib/ bin/cupid -c conf/config.cfg -u http://shop33220311.taobao.com/?tb ...
- SpringBoot集成jdbcTemplate/JPA
1.pom.xml <!-- jdbcTemplate 依赖 --> <dependency> <groupId>org.springframework.boot& ...
- Linux下设置oracle环境变量
Linux设置Oracle环境变量 方法一:直接运行export命令定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新s ...
- [Android]通过alias映射所有Busybox命令
# 把Busybox所有的命令通过alias映射出来(若此命令不存在时) # 这么做只是为了平时敲命令行时无须额外的打 busybox (感觉很麻烦的说) for applet in $(busybo ...
- JavaSE入门学习7:Java基础语法之语句(下)
继续接着Java基础语法来:JavaSE入门学习5:Java基础语法(一)和JavaSE入门学习6:Java基础语法(二). 语句 Java经常使用的3种循环:while.do...while,for ...
- Android开发之使用DefaultHandler处理XML数据
一.定义规则 XML数据结构定义 请记住上面的定义,后面我会用“标签开始”.“文本”.“标签结束”表示SAX正在处理哪部分XML数据 事件模型 为什么这里我要谈到这个,因为SAX处理XML数据是采用事 ...