ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Educational Codeforces Round 107 (Rated for Div. 2) G.Chips on a Board 倍增优化DP

2021-04-16 21:35:34  阅读:187  来源: 互联网

标签:Educational Rated int Codeforces leq 异或 棋子 端点 dp


Educational Codeforces Round 107 (Rated for Div. 2) G.Chips on a Board 倍增优化DP

题意

给定一个矩阵,保证每一行有一个棋子,两人轮流移动,每次可以选择一个棋子往左移动到任意一个位置,当不可移动时为败。

\(q\)次询问,每次询问表示只看\([L,R]\)列的矩阵时的胜败情况。

\[1 \leq n,m\leq2e5\\ 1 \leq c_i \leq m\\ 1 \leq q \leq 2e5\\ L \leq R\leq m \]

分析

容易发现这实际上是在玩Nim游戏。

不妨把\(n\)行的棋子拍成一行来看,问题转化为了,给定左端点和右端点,求所有落在左端点到右端点区间内的所有棋子到左端点距离的异或和。

\(dp[i][j]\)表示区间\([j,j + 2^i)\)的所有棋子到\(j\)的距离的异或和

\[dp[i][j] = dp[i - 1][j] + dp[i - 1][j + 2^{i-1}] \]

若\([j + 2^{i-1},j+2^i)\)有奇数个棋子,则还需要异或上\(2^{i-1}\)

感觉针对异或的,比较精妙的优化,问题在于每次差是2的若干次,只影响一位,因此可以一起统计

有了\(dp[i][j]\)后面就可以用相似方法方便计算了

代码

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

ll rd(){
	ll  x;
	scanf("%lld",&x);
	return x;
}

const int maxn = 6e5 + 5;

int _xor[20][maxn];

int main(){
	int n = rd();
	int m = rd();
	vector<int> v(n);
	for(int i = 0;i < n;i++)
		v[i] = rd();
	sort(v.begin(),v.end());
	vector<int> sum(m + 1);
	for(auto x:v)
		sum[x] ^= 1;
	for(int i = 2;i <= m;i++)
		sum[i] ^= sum[i - 1];
	for(int i = 1;i < 20;i++)
		for(int j = 1;j <= m && j + (1 << i) <= m;j++){
			_xor[i][j] = _xor[i - 1][j] ^ _xor[i - 1][j + (1 << (i - 1))];
			if((sum[j + (1 << i) - 1] ^ sum[j + (1 << (i - 1)) - 1]) & 1) _xor[i][j] ^= 1 << (i - 1);
		}
	int q = rd();
	while(q--){
		int l = rd();
		int r = rd();
		int ans = 0;
		for(int i = 20 - 1;i >= 0;i--){
			int nxt = l + (1 << i);
			if(nxt <= r) {
				int num = sum[r] ^ sum[nxt - 1];
				if(num & 1) ans ^= 1 << i;
				ans ^= _xor[i][l];
				l = nxt;
			}
		}
		cout << "AB"[ans == 0];
	}
}

标签:Educational,Rated,int,Codeforces,leq,异或,棋子,端点,dp
来源: https://www.cnblogs.com/hznumqf/p/14668800.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有