cf 1091 div2补题
A The Equalizer

如果开局所有数加起来的和为奇数的话,肖纳克一定可以赢;
如果和为偶数的话,肖纳克有一次作弊的机会,如果作弊完所有数的和为偶数的话,肖纳克也会赢,
其余情况均会输
B Flip the Bit (Easy Version)

对于一些连续的且不与特殊索引数相同的,可以通过一次变换使他们相同,然后特殊索引处的值想变回原值需要变换偶数次,如果左边有 l 个连续块(不同值的),那么就要变换 2*l次,同理,右边应该变换 2*r 次,加起来是 2l+2r 次,但可以两边一起变换,这样得到的结果就是 2*max(l,r) 次
C Grid Covering

不难发现,这就是一个环形的路,走出边界会从另一边走回来。
只看左右走的话,从1,1开始走,如果想走到这一行的所有位置,必须保证 gcd(n,a)=1,同理,如果想走到这一列的所有位置,必须保证 gcd(m,b)=1 也就是说这两个条件是必须满足的,又因为是要交替走,那么我们找一下运动周期,这个周期一定是m的倍数,也一定是n的倍数,所以最小周期就是lcm(n,m),然后因为是交替走,所以他还会有另外一条路线,周期也是lcm(n,m),所以他一共能经过 2*lcm(n,m) 这些不同的点,所以如果这个数大于 n*m ,那么就可以走完,反之走不完
D Flip the Bit (Hard Version)

有个小trick :一个01串的差分值,如果对其中【l,r】区间进行翻转,那么其差分数组中只有d\(l-1\)和d\(r\)会变化,其他均不会变化
那么我们在首尾分别加上一个与特殊位置相同的数,对其进行差分,得到差分数组,结果应该是使得所有元素全为0,只需要找出一共多少个1,记为sum。
故若没有限制,最小的次数应该是\(ceil(sum/2)\),但题目说了必须包含至少一个特殊位置,所以需要找出这特殊位置分开的若干的块中含要处理的地方最多的一个块,记为mx,答案就是\(max(mx,ceil(sum/2))\)
void solve()
{
cin >> n >> k;
vi a(n + 7);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
vi p(k + 7);
for (int i = 1; i <= k; i++)
{
cin >> p[i];
}
int ans = 0;
int now = 0;
int mx = 0;
vi d(n + 1);
int cnt = 1;
a[0] = a[p[1]], a[n + 1] = a[p[1]];
for (int i = 0; i <= n; i++)
{
int c = a[i] ^ a[i + 1];
now += c;
ans += c;
if (i + 1 == p[cnt])
{
cnt++;
mx = max(now, mx);
now = 0;
}
}
mx = max(now, mx);
cout << max((ans + 1) / 2, mx) << endl;
}

浙公网安备 33010602011771号