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

来源:互联网 发布:课时优化八上英语答案 编辑:程序博客网 时间:2024/05/16 17:29

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;}
阅读全文
1 0
原创粉丝点击