2015 百度之星 1002 找连续数 暴力

找连续数

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();
    }
}

 

posted @ 2015-05-31 19:35  qscqesze  阅读(410)  评论(0编辑  收藏  举报