列表

详情


NC15430. 区间的值域连续段

描述

给你一个序列,每次查询一段区间中长度为 1,2,...,10 的极长值域连续段个数
定义值域连续段为:
把区间里面所有数排序后去重,设排序后得到的序列为 b
如果对于二元组(l,r) 满足 bl,bl+1,...,br 中每个数为前一个数 +1
而且对于二元组(l,r+1),(l-1,r) 均不满足,我们称 (l,r) 为一个长度为 r-l+1 的极长值域连续段

输入描述

第一行两个数n,m,表示序列的长度和查询的次数
之后一行n个数表示这个序列
之后m行每行两个数l,r表示查询的区间

输出描述

对于每次询问,输出一个长度为10的字符串,第i个字符表示长度为i的极长连续段个数mod 10的结果

示例1

输入:

5 5
1 2 4 5 6
1 5
1 2
3 4
3 5
4 5

输出:

0110000000
0100000000
0100000000
0010000000
0100000000

示例2

输入:

8 9
2 3 3 3 3 6 6 6
1 8
2 3
4 5
6 8
1 2
3 4
5 6
3 8
5 5

输出:

1100000000
1000000000
1000000000
1000000000
0100000000
1000000000
2000000000
2000000000
1000000000

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 569ms, 内存消耗: 23924K, 提交时间: 2018-04-02 08:50:16

#include<bits/stdc++.h>
#define MAXN 1000050
using namespace std;
int N,M;
char ans[MAXN][15];
int A[MAXN],pos[MAXN];
struct Query{
	int l,r,id;
	bool operator < (const Query &rtm) const{
		return r<rtm.r;
	}
}Q[MAXN];
struct BIT{
	int a[11][MAXN],n;
	#define Lowbit(x) (x&(-x))
	void Modify(int k,int p,int v){
		for(;p<=n;p+=Lowbit(p)) a[k][p]+=v;
	}
	int Query(int k,int p,int ret=0){
		for(;p;p-=Lowbit(p)) ret+=a[k][p];
		return ret;
	}
}DT;
int main(){
	scanf("%d%d",&N,&M); DT.n=1000000;
	for(int i=1;i<=N;i++) scanf("%d",&A[i]);
	for(int i=1;i<=M;i++) Q[i].id=i,scanf("%d%d",&Q[i].l,&Q[i].r);
	sort(Q+1,Q+M+1);
	for(int i=1,j=1;i<=N&&j<=M;i++){
		int last=pos[A[i]],cur=i,ll=0,rr=0,pre;
		while(cur>last&&(ll<=10||rr<=10)){
			pre=cur; cur=last;
			if(ll<=10) cur=max(cur,pos[max(A[i]-ll-1,0)]);
			if(rr<=10) cur=max(cur,pos[min(A[i]+rr+1,1000000)]);
			if(ll&&ll<=10) DT.Modify(ll,cur+1,-1),DT.Modify(ll,pre+1,1);
			if(rr&&rr<=10) DT.Modify(rr,cur+1,-1),DT.Modify(rr,pre+1,1);
			if(ll+rr+1<=10) DT.Modify(ll+rr+1,cur+1,1),DT.Modify(ll+rr+1,pre+1,-1);
			while(ll<=10&&A[i]-ll-1>=1&&pos[A[i]-ll-1]>=cur) ++ll;
			while(rr<=10&&A[i]+rr+1<=1000000&&pos[A[i]+rr+1]>=cur) ++rr;
		}
		for(pos[A[i]]=i;j<=M&&Q[j].r==i;j++)
			for(int k=1;k<=10;k++)
				ans[Q[j].id][k]='0'+DT.Query(k,Q[j].l)%10;
	}
	for(int i=1;i<=M;i++) puts(ans[i]+1);
	return 0;
}

上一题