HDU 4638 Group
来源:互联网 发布:购物软件需求分析报告 编辑:程序博客网 时间:2024/06/01 19:37
主要借鉴这一篇:http://www.2cto.com/kf/201308/233187.html
思路:如果我们从左到右一个个加进来,那么对于加进来的第i个数num[i],那么它就能增加一个段(num[i]+1,和num[i]-1在之前都没出现过),或者减少一个段(num[i]+1,和num[i]-1在之前都出现过),或者不增不减(num[i]+1,和num[i]-1在之前只出现过其中一个)。那么我们要找的询问的区间[l,r]内有多少个区间,就是询问[l,r]内的数,增加了几个这样的段。但是直接询问[l,r]内的数产生的段数是不可以的,因为对于[l,r]内的某一个数,有可能它所能产生的段数是跟l之前,或者r之后的数有关的。因此我们可以将询问离线出来,按r排好序,每次询问之前,将r之前的数产生的影响先清除掉,也就是对于某个在r之前的数,将它所能影响的后面的数能增加的段去除,对于之前的已经不用管了,因为我们按右端点排序,所以在清除某一个数时,它前面的数的影响之前已经处理掉了。所以这个区间的段数自然就是[l,r]的区间和。
线段树和树状数组都能做,这里附上两份代码:
线段树:
#include <cstdio>#include <cstring>#include <string>#include <iostream>#include <map>#include <vector>#include <cmath>#include <stack>#include <queue>#include <cstdlib>#include <algorithm>using namespace std;typedef __int64 int64;typedef long long ll;#define M 100005#define mod 1000000007struct node{int l , r , val;}tree[M*4] , tp[M];int num[M] , pos[M] , ans[M];bool vis[M];bool cmp(node a , node b){if (a.r < b.r)return true;return false;}void Build(int l , int r , int rt){tree[rt].l = l;tree[rt].r = r;tree[rt].val = 0;if (l == r)return;int mid = (l+r)>>1;Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1);}void Updata(int rt , int pos , int val){int l = tree[rt].l;int r = tree[rt].r;tree[rt].val += val;if (l == r)return;int mid = (l+r)>>1;if (pos <= mid)Updata(rt<<1,pos,val);else Updata(rt<<1|1,pos,val);}int Query(int rt , int l , int r){if (l == tree[rt].l && r == tree[rt].r)return tree[rt].val;int mid = (tree[rt].l+tree[rt].r)>>1;if (r <= mid)return Query(rt<<1,l,r);if (l > mid)return Query(rt<<1|1,l,r);return Query(rt<<1,l,mid)+Query(rt<<1|1,mid+1,r);}int main(){int n , m , i , t;scanf("%d",&t);while (t--){scanf("%d%d",&n,&m);memset(vis , 0 , sizeof vis);for (i = 1 ; i <= n ; i++){scanf("%d",num+i);pos[num[i]] = i;}for (i = 1 ; i <= m ; i++){scanf("%d%d",&tp[i].l,&tp[i].r);tp[i].val = i;}sort(tp+1 , tp+m+1 , cmp);Build(1,n,1);int cnt = 1;ans[1] = ans[2] = -5;for (i = 1 ; i <= n ; i++){Updata(1,i,1);vis[num[i]] = 1;if (vis[num[i]+1])Updata(1,pos[num[i]+1],-1);if (vis[num[i]-1])Updata(1,pos[num[i]-1],-1);while (i == tp[cnt].r && cnt <= m){ans[tp[cnt].val] = Query(1,tp[cnt].l,tp[cnt].r);cnt++;}}for (i = 1 ; i <= m ; i++)printf("%d\n",ans[i]);}return 0;}
树状数组:
#include <cstdio>#include <cstring>#include <string>#include <iostream>#include <map>#include <vector>#include <cmath>#include <stack>#include <queue>#include <cstdlib>#include <algorithm>using namespace std;typedef __int64 int64;typedef long long ll;#define M 100005#define mod 1000000007struct node{int l , r , val;}tp[M];int n , m , num[M] , pos[M] , ans[M] , sum[M];bool vis[M];bool cmp(node a , node b){if (a.r < b.r)return true;return false;}int Lowbit(int x){return x&(-x);}void Updata(int pos , int val){while (pos <= n){sum[pos] += val;pos += Lowbit(pos);}}int Query(int l , int r){int ret = 0;while (r > 0){ret += sum[r];r -= Lowbit(r);}l--;while (l > 0){ret -= sum[l];l -= Lowbit(l);}return ret;}int main(){int i , t;scanf("%d",&t);while (t--){scanf("%d%d",&n,&m);memset(vis , 0 , sizeof vis);memset(sum , 0 , sizeof sum);for (i = 1 ; i <= n ; i++){scanf("%d",num+i);pos[num[i]] = i;}for (i = 1 ; i <= m ; i++){scanf("%d%d",&tp[i].l,&tp[i].r);tp[i].val = i;}sort(tp+1 , tp+m+1 , cmp);int cnt = 1;for (i = 1 ; i <= n ; i++){Updata(i,1);vis[num[i]] = 1;if (vis[num[i]+1])Updata(pos[num[i]+1],-1);if (vis[num[i]-1])Updata(pos[num[i]-1],-1);while (i == tp[cnt].r && cnt <= m){ans[tp[cnt].val] = Query(tp[cnt].l,tp[cnt].r);cnt++;}}for (i = 1 ; i <= m ; i++)printf("%d\n",ans[i]);}return 0;}
- hdu 4638 Group
- HDU 4638 Group
- hdu 4638 Group
- HDU-4638-Group
- hdu 4638 Group
- hdu 4638 Group(莫队)
- HDU 4638 Group 【莫队】
- hdu 4638 Group
- hdu 4638——Group
- hdu 4638 Group 树状数组
- HDU 4638 Group(树状数组)
- HDU 4638 Group (树状数组)
- HDU Group
- hdu 4638 Group 多校第四场
- hdu 4638 Group (树状数组+离线)
- hdu 4638 Group(离线线段树)
- HDU 4638 Group(离线 + 树状数组)
- Hdu 4638 Group 离线+树状数组
- 善用encodeURI解决AJAX在IE10以下浏览器中的莫名BUG
- yii路径
- C代码简洁之道-函数宏定义
- Tomcat:开源技术基础:教你如何熟练使用TOMCAT
- android触屏事件处理onInterceptTouchEvent的问题
- HDU 4638 Group
- Fiddler (三) Composer创建和发送HTTP Request
- URL-基本知识
- Linux下build和使用rabbitmq-c
- LVS 三种工作模式的优缺点比较
- listview 为什么点击没有反应
- VC++读写配置文件
- Openfiler之二:Openfiler的配置
- VC++学习之线程篇