找连续数
Time Limit: 20 Sec Memory Limit: 256 MB
题目连接
http://acdream.info/problem?pid=1751
Description
小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的。
现在小度熊增加题目难度,他不想知道是否有这样的 k 的区间,而是想知道有几个这样的 k 的区间。
Input
输入包含一组测试数据。
第一行包含两个整数n,m,n代表数组中有多少个数字,m 代表针对于此数组的询问次数,n不会超过10的4次方,m 不会超过1000。第二行包含n个正整数,第 I 个数字代表无序数组的第 I 位上的数字,数字大小不会超过2的31次方。接下来 m 行,每行一个正整数 k,含义详见题目描述,k 的大小不会超过1000。
Output
第一行输"Case #i:"。(由于只有一组样例,只输出”Case #1:”即可)
然后对于每个询问的 k,输出一行包含一个整数,代表数组中满足条件的 k 的大小的区间的数量。
Sample Input
6 2 3 2 1 4 3 5 3 4
Sample Output
Case #1: 2 2
HINT
题意
题解:
很显然,判定条件就是在这一段没有重复的数,而且这一段数的最大值减去最小值恰好等于这一段的长度
那么我们直接预处理就好了,复杂度是O(nm)的
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define test freopen("test.txt","r",stdin) #define maxn 2000001 #define mod 10007 #define eps 1e-9 int Num; char CH[20]; const int inf=0x3f3f3f3f; const ll infll = 0x3f3f3f3f3f3f3f3fLL; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } inline void P(int x) { Num=0;if(!x){putchar(‘0‘);puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); puts(""); } //************************************************************************************** int n,m; int a[maxn]; int ans[1001]; map<int,int> mp; int Max[maxn]; int Min[maxn]; int pre[maxn]; int f[maxn]; void init() { n=read(),m=read(); for(int i=0;i<n;i++) a[i]=read(); for(int i=0;i<n;i++) { Max[i]=Min[i]=a[i]; if(mp.find(a[i])==mp.end())pre[i]=-1; else pre[i]=mp[a[i]]; mp[a[i]]=i; f[i]=1; } for(int i=1;i<=1000;i++) { ans[i]=0; for(int j=0;j+i<n+1;j++) { if(!f[j]) continue; if(Max[j]-Min[j]+1!=i) continue; ans[i]++; } for(int j=0;j+i<n;j++) { Max[j]=max(Max[j],a[i+j]); Min[j]=min(Min[j],a[i+j]); if(pre[i+j]>=j) f[j]=0; } } } void solve() { init(); for(int i=0;i<m;i++) { int tmp=read(); printf("%d\n",ans[tmp]); } } int main() { //test; int t=1; for(int cas=1;cas<=t;cas++) { printf("Case #%d:\n",cas); solve(); } }
时间: 2024-10-13 00:16:30