Gym - 101608G WiFi Password 尺取+线段树

本文介绍了一个算法问题的解决方法,通过使用线段树来维护区间或运算值,并结合滑动窗口技巧找到最大连续子数组,使得或运算结果不超过给定阈值。该算法的时间复杂度为O(n log n)。

题目链接:点击查看

题意:求个最大的连续区间,要求or值小于等于v

题解:尺取走一下,然后线段树维护下区间or值,n*log(n)的复杂度

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
	int l,r;
	int val;
}tree[N<<2];
int n,m;
int a[N];
void pushup(int cur)
{
	tree[cur].val=tree[cur<<1].val|tree[cur<<1|1].val;
}
void build(int l,int r,int cur)
{
	tree[cur].l=l;
	tree[cur].r=r;
	if(l==r)
	{
		scanf("%d",&tree[cur].val);
		a[tree[cur].l]=tree[cur].val;
		return;
	}
	int mid=(r+l)>>1;
	build(l,mid,cur<<1);
	build(mid+1,r,cur<<1|1);
	pushup(cur);
} 
int query(int pl,int pr,int cur)
{
	if(pl<=tree[cur].l&&tree[cur].r<=pr)
		return tree[cur].val;
	int res=0;
	if(pl<=tree[cur<<1].r) res|=query(pl,pr,cur<<1);
	if(pr>=tree[cur<<1|1].l) res|=query(pl,pr,cur<<1|1);
	return res;
}
int main()
{
	freopen("wifi.in","r",stdin);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		build(1,n,1);
		int ans=0;
		int l=1,r=1;
		int cnt=0,flag;
		while(r<=n+1)
		{
			while(r<=n+1)
			{
				if(r-1 >= l)
				{
					cnt=query(l,r-1,1);
					if(cnt <= m)
						ans=max(ans,r-l);
					else 
						break;
				}
				r++;
			}
			l++;
		}
		printf("%d\n",ans);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值