列表

详情


NC214574. 牛牛的数列

描述

牛牛有一个数列,数列有个数,第个数记为同时。牛牛有两个数 ,

,现在牛牛想要问你几个问题,每个问题都对应一个区间

定义一个点 ( )

当i 时, 恒成立

注:如果有多个k满足上式,那么k取最靠左的那一个

定义一个数

区间除去点k的的异或和

= ...... (不会参加异或)

牛牛想要你输出 的最大值 ( )

。牛牛会问你次这样的问题

提示:题目描述中的变量区分大小写

输入描述

第一行包含四个整数n,q,s,w。
接下来一行有n个数,a_i
接下来q行,每行两个整数 l r。

输出描述

对于每次询问输出一行

示例1

输入:

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

输出:

4
5

说明:

第一次询问是1-5,此时区间内与3异或出的值最大的数是16,除去16,这个区间异或和为0,0与1-4中的数异或能得到的最大的数是4.(0 xor 4 = 4)故输出4.
第二次询问是2-4,此时区间内与3异或出的值最大的数是16,除去16,这个区间异或和为1,1与1-4中的数异或能得到的最大的数是5.(1 xor 4 = 5)故输出5.

原站题解

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

C++(g++ 7.5.0) 解法, 执行用时: 967ms, 内存消耗: 250636K, 提交时间: 2023-04-02 09:45:45

#include<bits/stdc++.h>
using namespace std;
#define f(i,a,b) for(int i=(a); i<=(b); i++)
#define uf(i,a,b) for(int i=(a); i>=(b); i--)
int n, q, s, w,l,r;
pair<int, int>f[(int)1e6+9][30];
int pre[(int)1e6];
int arr[(int)1e6];
int main() {
	scanf("%d%d%d%d",&n,&q,&s,&w);
	f(i,1,n){
		 scanf("%d",arr+i);
		f[i][0] = { arr[i] ^ s,-i };
		pre[i] = pre[i - 1] ^ arr[i];
	}
	for (int j = 1; (1 << j) <= n; j++) {
		for (int i = 1; i +(1<<j) - 1 <= n; i++) {
			f[i][j] = max(f[i][j - 1], f[i + ( 1 << (j - 1))][j - 1]);
		}
	}
	while (q--) {
		scanf("%d%d",&l,&r);
		int len = __lg(r-l+1);
		auto it = max(f[l][len], f[r - (1 << len)+1][len]);
		int  ss = (pre[r] ^ pre[l - 1] ^ arr[-it.second]);
		int ww = 0;
		uf(i,33,0){
			if ((ss>> i) & 1)continue;
			if(ww+((long)1<<i)>w) continue;
			ww |= 1 << i;
        }
		printf("%d\n",ss^ww);
	}

	return 0;
}

C++(clang++11) 解法, 执行用时: 721ms, 内存消耗: 99132K, 提交时间: 2020-12-28 17:59:45

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a,ss[N],n,m,s,w,lg[N],f[N][21];
int getmax(int l,int r){int k=lg[r-l+1];return max(f[l][k],f[r-(1<<k)+1][k]);}
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&w),lg[0]=-1;
    for(int i=1;i<=n;i++)scanf("%d",&a),f[i][0]=a^s,ss[i]=ss[i-1]^a,lg[i]=lg[i/2]+1;
	for(int j=1;(1<<j)<=n;++j)for(int i=1;i+(1<<(j-1))<=n;++i)
	f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    while(m--)
	{
		int l,r;scanf("%d%d",&l,&r);
	    int ans=ss[r]^ss[l-1]^getmax(l,r)^s,res=0;
	    for(int k=29;~k;--k)if(!(ans&(1<<k))&&res+(1<<k)<=w)res+=(1<<k);
        printf("%d\n",ans^res);
    }
    return 0;
}

上一题