您的位置:首页 > 产品设计 > UI/UE

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

2017-06-30 20:08 525 查看

Description



Input



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



Solution

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

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

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

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

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

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

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

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

Code

#include<cstdio>
using namespace std;
const int N=1e6+1,Mx=2147483647;
int f[N<<2],a
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: