BOJ 13704 | 수열과 쿼리 11

전승민·2023년 4월 19일
0

BOJ 기록

목록 보기
13/68

수열과 쿼리 0에서 쓰인 prefix sum과 비슷한 기법을 사용한 문제이다.

prefix xor 정도로 부를 수 있겠다.

XOR 연산의 성질인 교환법칙과 결합법칙이 성립한다 정도만 생각해도 풀 수 있겠다.

AiA_i ^ Ai+1A_{i+1} ^ ... ^ Aj=KA_{j}=K[i,j][i, j] 를 찾는 것은 다음과 같이 바꿔 쓸 수 있다.

A1A_{1} ^ ... ^ Ai=XiA_{i}=X_{i} 일 때, Xi1X_{i-1} ^ Xj=KX_j = K

XOR 연산의 특징인 aa ^ a=0a = 0 을 생각하면 이해가 될 것이다.

따라서 Xj=Xi1X_j = X_{i-1} ^ KK 이므로 새로운 jj가 들어올 때마다 이 식을 만족하는 i1i-1의 개수를 찾아주면 된다.

당연히 완전탐색으로 찾으면 큰일나고 cnt 배열을 만들어서 관리해줘야 한다.

[l,r][l, r] 이 바뀌면 삽입되거나 삭제된 값을 cnt에도 업데이트 해줘야 한다.

대강 이렇게 생각하고 작성했더니 몇번 트라이 끝에 맞았다.

여담이지만 #define endl '\n' 이랑 FASTIO 안 쓰고 제출했다가 계속 TLE 났다...
항상 확인하도록 하자.

#include <bits/stdc++.h>
using namespace std;

#define lint long long

int N, K;
int Q;
lint cnt[1100005];
lint arr[100005];

struct Query{
	int l, r;
	int idx;
};

#define FASTIO ios_base::sync_with_stdio;cin.tie(nullptr);

#define debug if constexpr (local) std::cout
#define endl '\n'

const int SIZE_PER_BUCKET = 300;
const int BUCKET_SIZE = 1111111/SIZE_PER_BUCKET + 20;

bool _cmp(Query a, Query b){
	if (a.l/SIZE_PER_BUCKET != b.l/SIZE_PER_BUCKET)
		return a.l/SIZE_PER_BUCKET < b.l/SIZE_PER_BUCKET;
	return a.r < b.r;
}

vector<Query> q;
lint ans[100005];

int main(){
	FASTIO;
	cin >> N >> K;
	for (int i = 1; i <= N; i++){
		cin >> arr[i];
	}
	//prefix xor
	for (int i = 2; i <= N; i++) arr[i] ^= arr[i-1];
	
	cin >> Q;
	
	for (int i = 0; i < Q; i++){
		int a, b; cin >> a >> b;
		q.push_back({a-1, b, i});
	}
	sort(q.begin(), q.end(), _cmp);
	
	int lp = q[0].l, rp = lp-1;
	lint sum = 0;
	
	for (int i = 0; i < Q; i++){
		int l = q[i].l; int r = q[i].r;
		int idx = q[i].idx;
		
		while (rp < r){
			rp++;
			sum += cnt[K ^ arr[rp]];
			cnt[arr[rp]]++;
		}
		
		while (l < lp){
			lp--;
			sum += cnt[K ^ arr[lp]];
			cnt[arr[lp]]++;
		}
		
		while (rp > r){
			cnt[arr[rp]]--;
			sum -= cnt[K ^ arr[rp]];
			rp--;
		}
		
		while (lp < l){
			cnt[arr[lp]]--;
			sum -= cnt[K ^ arr[lp]];
			lp++;
		}
		
		ans[idx] = sum;
	}
	
	for (int i = 0; i < Q; i++){
		cout << ans[i] << endl;
	}
	
}
profile
알고리즘 공부한거 끄적이는 곳

0개의 댓글