列表

详情


NC201977. 最小鸽

描述

对于一排鸽子,每个鸽子有一个鸽值
定义某一区间内鸽子的鸽子的程度为这段区间内鸽值的最大值
定义某一区间内鸽子的不鸽的程度位这段区间内鸽值的或
现在你需要某一只鸽子代替你去做户外的事情,但是只有一段区间内的鸽子的
不鸽程度大于这段区间内鸽子程度时,这些鸽子才愿意出动
那么每次选定一只鸽子,请你回答:最少要同时出动多少只鸽子?

输入描述

第一行两个数字: n,m 表示鸽子的数量和询问的数量
第二行 n 个数字,第 i 个数字表示第 i 只鸽子的鸽值
接下来 m 行,每行一个数字,请你回答包含要让这只鸽子出动最少需要同时出动几只鸽子

输出描述

对于每个询问,输出一行一个整数

如果无论如何都不能让这只鸽子出动,请输出一行一个数字 -1

示例1

输入:

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

输出:

2
2
3
4
2
2
2
2

说明:

对于 30% 的数据 n,m<=2000
对于 60% 的数据 n,m<=6000
对于 100% 的数据, n,m<=300000
所有鸽子的鸽值小于等于1e9

原站题解

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

C++14(g++5.4) 解法, 执行用时: 82ms, 内存消耗: 2540K, 提交时间: 2020-05-06 09:51:36

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MX=3e5+9;
int n,m,x;
ll a[MX];

int solve(int x,int r){
    ll mx=0,huo=0;
    for( int i=r ; i>=1 ; i-- ){
        mx=max(mx,a[i]);
        huo|=a[i];
        if( huo>mx && i<=x )
            return r-i+1;
    }
    return -1;
}

int main()
{
//    freopen("input.txt","r",stdin);
    scanf("%d %d",&n,&m);
    for( int i=1 ; i<=n ; i++ )
        scanf("%lld",&a[i]);
    while( m-- ){
        scanf("%d",&x);
        ll huo=0;
        int r=n,ans=-1;
        for( int i=x ; i<=r ; i++ ){
            if( huo|a[i]!=huo ){
                huo|=a[i];
                int temp=solve(x,i);
                if( temp==-1 )
                    continue;
                if( ans==-1 )
                    ans=temp;
                else 
                    ans=min(ans,temp);
                r=min(r,i+ans+1);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 52ms, 内存消耗: 1764K, 提交时间: 2020-05-02 21:47:44

#include<bits/stdc++.h>
#define ll long long
using namespace std;

inline ll read(){
	ll num=0,neg=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')neg=-1;c=getchar();}
	while(isdigit(c)){num=(num<<3)+(num<<1)+c-'0';c=getchar();}
	return num*neg;
}

int n,Q,a[300010];

inline int solve(int now,int x){
	int tmp=0,res=0;
	for(int i=now;i>=1;i--){
		tmp=max(tmp,a[i]);res|=a[i];
		if(res>tmp&&i<=x) return now-i+1;
	}return -1;
}

int main(){
	n=read(),Q=read();
	for(int i=1;i<=n;i++) a[i]=read();
	while(Q--)
	{
		int x=read(),now=0,ans=-1,r=n;
		for(int i=x;i<=r;i++)
			if((now|a[i])!=now){
				now|=a[i];
				int tmp=solve(i,x);
				if(tmp==-1) continue;
				if(ans==-1) ans=tmp;
				else ans=min(ans,tmp);
				r=min(r,x+ans+1);
			}
		printf("%d\n",ans);
	}return 0;
	
}

上一题