BZOJ4975 区间翻转

题目大意

有一个长度为 n n n的序列 a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,,an。小 Q Q Q和小 T T T在玩游戏。两人轮流操作,小 Q Q Q先手。对于每次操作,玩家需要选择一个长度为 4 x + 2 4x+2 4x+2 4 x + 3 4x+3 4x+3的区间 [ l , r ] [l,r] [l,r],其中 x x x是玩家自行选择的非负整数。然后将 a l , a l + 1 , … , a r − 1 , a r a_l,a_{l+1},\dots,a_{r-1},a_r al,al+1,,ar1,ar翻转。每次操作之后得到的新序列的字典序必须比操作前的序列大。第一个不能继续操作的玩家输。假设小 Q Q Q和小 T T T都采取最优策略,问谁会获胜。如果小 Q Q Q获胜,则输出 Q Q Q;如果小 T T T获胜,则输出 T T T

数据范围

q ≤ 50 ≤ n , 1 ≤ a i ≤ n q\leq 50\leq n,1\leq a_i\leq n q50n,1ain a i a_i ai互不相同。


题解

首先,我们知道在区间翻转后,该区间的顺序对和逆序对的数量互换。

观察题目所给的选择范围 4 x + 2 4x+2 4x+2 4 x + 3 4x+3 4x+3

  • 4 x + 2 4x+2 4x+2的区间内的顺序对和逆序对的和为 ( 4 x + 2 ) ( 4 x + 1 ) 2 = ( 2 x + 1 ) ( 4 x + 1 ) \dfrac{(4x+2)(4x+1)}{2}=(2x+1)(4x+1) 2(4x+2)(4x+1)=(2x+1)(4x+1)
  • 4 x + 3 4x+3 4x+3的区间内的顺序对和逆序对的和为 ( 4 x + 3 ) ( 4 x + 2 ) 2 = ( 4 x + 3 ) ( 2 x + 1 ) \dfrac{(4x+3)(4x+2)}{2}=(4x+3)(2x+1) 2(4x+3)(4x+2)=(4x+3)(2x+1)

我们发现,区间内的顺序对和逆序对的和一定为奇数。那么一次翻转之后,整个序列的顺序对和逆序对的奇偶性都取反。

在游戏结束时, a a a序列是递减序列,顺序对的个数为 0 0 0。那么如果当前的顺序对的个数是偶数,则不管你怎么旋转,接下来的顺序对的个数一定是奇数,对手在翻回偶数,当到 0 0 0时你就输了。如果当前的顺序对的个数是奇数,则你一定会胜利。

所以,我们可以先算出顺序对的个数。如果为奇数,则先手必胜;如果为偶数,则后手必胜。

时间复杂度为 O ( n 2 ) O(n^2) O(n2)

code

#include<bits/stdc++.h>
using namespace std;
int n,fl=0,a[55];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<i;j++){
			if(a[i]>a[j]) ++fl;
		}
	}
	if(fl%2==1) printf("Q");
	else printf("T");
	return 0;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值