JZOJ 5185. 【NOIP2017提高组模拟6.30】tty's sequence

Description

Description

Input

Input

Output

Output

Sample Input

input 1:

6 3
1 1 1 0 0 0

input 2:

6 3
1 1 0 1 0 0

input 3:

6 3
11 8 2 1 3 9

Sample Output

output 1

1 1

output 2

1 0

output 3

11 1

Data Constraint

Data Constraint

Solution

  • 首先要仔细观察题意和思考其内在本质,我们可以发现:

  • ①:最大的或值一定是全选的(越多越好,反正不会变小),可以 O(N) 直接求出。

  • ②:最大的与值一定是选 K 个(越少越好,多了又不会变大)。

  • 那么如何求与值呢?枚举区间的左端点,在 O(K) 计算?

  • 不!这样的话总时间复杂度可能达到 O(NK) ,并不可取。

  • 于是,我们就可以使用线段树,维护整个区间的与值。

  • 那么我们在枚举区间的左端点时,就可以 O(logN) 查找区间的与值。

  • 最终的时间复杂度就是 O(NlogN) ,可以通过本题。

Code

#include<cstdio>
using namespace std;
const int N=1e6+1,Mx=2147483647;
int f[N<<2],a[N];
int ans1,ans2,num;
inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}
inline void make(int v,int l,int r)
{
    if(l==r)
    {
        f[v]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    make(v<<1,l,mid);
    make(v<<1|1,mid+1,r);
    f[v]=f[v<<1]&f[v<<1|1];
}
inline void query(int v,int l,int r,int x,int y)
{
    if(l==x && r==y)
    {
        num&=f[v];
        return;
    }
    int mid=(l+r)>>1;
    if(y<=mid) query(v<<1,l,mid,x,y); else
        if(x>mid) query(v<<1|1,mid+1,r,x,y); else
        {
            query(v<<1,l,mid,x,mid);
            query(v<<1|1,mid+1,r,mid+1,y);
        }
}
int main()
{
    int n=read(),k=read();
    for(int i=1;i<=n;i++) ans1|=a[i]=read();
    if(n<=100 || k<=10)
        for(int i=1;i<=n-k+1;i++)
        {
            int s=Mx;
            for(int j=i;j<i+k;j++) s&=a[j];
            if(s>ans2) ans2=s;
        }
    else
    {
        make(1,1,n);
        for(int i=1;i<=n-k+1;i++)
        {
            num=Mx;
            query(1,1,n,i,i+k-1);
            if(num>ans2) ans2=num;
        }
    }
    printf("%d %d",ans1,ans2);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值