HDU 6579 [2019 Multi-University Training Contest 1]

Operation

Problem Description

There is an integer sequence a of length n and there are two kinds of operations:
0 l r: select some numbers from al…ar so that their xor sum is maximum, and print the maximum value.

1 x: append x to the end of the sequence and let n=n+1.

Input

There are multiple test cases. The first line of input contains an integer T(T≤10), indicating the number of test cases.
For each test case:
The first line contains two integers n,m(1≤n≤5×105,1≤m≤5×105), the number of integers initially in the sequence and the number of operations.
The second line contains n integers a1,a2,…,an(0≤ai<230), denoting the initial sequence.
Each of the next m lines contains one of the operations given above.
It’s guaranteed that ∑n≤106,∑m≤106,0≤x<230.
And operations will be encrypted. You need to decode the operations as follows, where lastans denotes the answer to the last type 0 operation and is initially zero:
For every type 0 operation, let l=(l xor lastans)mod n + 1, r=(r xor lastans)mod n + 1, and then swap(l, r) if l>r.
For every type 1 operation, let x=x xor lastans.

Output

For each type 0 operation, please output the maximum xor sum in a single line.

Sample Input

1
3 3
0 1 2
0 1 1
1 3
0 3 4

Sample Output

1
3

思路

给出n个数,然后给出两种操作,一种是往数组加一个数,另一种是求出给定区间的最大异或值。贪心,但是不知道异或应该怎么贪,专门去看了线性基详解,大概能够理解一点,给出的几个模板刚好能够用上。估计这道题卡时间,补题过程中各种TLE,MLE,把数组缩小,输入输出全部改掉,修了一个下午的bug终于AC了。

代码

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1e6+5;
typedef long long ll;
#define debug printf("debug\n");

int t,n,m,p,cot;
ll lastans;
int a,d[maxn][31],pos[maxn][31];  //这里的31我开大一点就炸了

void add(int x) {
	for(int i=0; i<=30; i++) {
		d[cot][i] = d[cot-1][i];
		pos[cot][i] = pos[cot-1][i];
	}
	for(int i=30; i>=0; i--) {
		if(x&(1<<i)) { //注意,如果i大于31,前面的1的后面一定要加ll
			if(d[cot][i]) {
				if(p > pos[cot][i]) {
					swap(d[cot][i],x);
					swap(pos[cot][i],p);
				}
				x^=d[cot][i];
			} else {
				d[cot][i] = x;
				pos[cot][i] = p;
				break;//记得如果插入成功一定要退出
			}
		}
	}
}

int zeroDecrypt(int num) {
	return (num ^ lastans) % n + 1;
}

ll zeroOperation(int l, int r) {
	ll ans = 0;
	for(int i=30; i>=0; i--) {//记得从线性基的最高位开始
		if(pos[r][i] >= l) {
			ans = max(ans^d[r][i],ans);
		}
	}
	return ans;
}

int oneDecrypt(int num) {
	return num ^ lastans;
}

int main() {
	while(scanf("%d",&t) != EOF) {
		while(t--) {
			memset(d, 0, sizeof(d));
			memset(pos, 0, sizeof(pos));
			scanf("%d%d",&n,&m);
			lastans = 0;
			cot = 0;
			for(int i=1; i<=n; i++) {
				cin >> a;
				cot = p = i;
				add(a);
			}
			int make,l,r,x;
			while(m--) {
				scanf("%d",&make);
				switch(make) {
					case 0 : {
						scanf("%d%d",&l,&r);
						l = zeroDecrypt(l);
						r = zeroDecrypt(r);
						if(l > r) {
							swap(l,r);
						}
						lastans = zeroOperation(l,r);
						printf("%lld\n",lastans);
						break;
					}
					case 1 : {
						scanf("%d",&x);
						x = oneDecrypt(x);
						cot = p = ++n;
						add(x);
						break;
					}
				}
			}
		}
	}
}

题目来源

HDU 6579 Operation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值