原文链接 https://www.cnblogs.com/cly-none/p/9800105.html

题意:给出一个三行\(n\)列的矩阵。问它能否由满足\(a_{ij} = 3(j-1) + i\)的初始矩阵通过有限次中心对称其中的一个\(3 \times 3\)子矩阵的操作得到。

\(5 \leq n \leq 10^5\)

首先,我们容易发现,无论如何操作,每一列都是形如\(3k+1, \, 3k+2, \, 3k+3\)的3个数,并且要么是顺序要么是倒序。我们记恰是原来第\(i\)列的一列的权值为\(i\),恰是原来第\(i\)列上下翻转为\(-i\)。那么,我们每一次操作,就变成了选取相邻的3列,交换左边和右边两列的权值并把这3个权值取负。

然后,我们还能得到偶数权值只可能存在于偶数列中,奇数权值只存在于奇数列中。

然而,仅此还不足以成为充分条件,我们需要进一步分析。

一般而言,这类问题的关键在于发现“不变量”,即一次操作前后都不会发生变化的量。

于是考虑一次操作。它由两个部分组成:把所有列按奇偶性分为两组后,交换并取反一组中相邻的两列;并取反另一组中对应位置的一列。让我们先勉为其难地放弃充分性,分开考虑这两部分而忽略一部分联系:

  • 操作1:交换两个相邻元素。
  • 操作2:取反一个元素。

这两个操作都很简洁,容易分析。

对于操作1,通过逆序对分析我们能得到,如果初始状态和结束状态已知,那么它操作总数的奇偶性是固定的。同样,操作2也有这个性质。

同时,我们注意到,奇数列中操作1的个数等于偶数列中操作2的个数。这意味着,奇数列的逆序对数的奇偶性与偶数列中负数个数的奇偶性相同。反之亦然。

又是一个充分条件,但已经挺复杂了。利用搜索程序验证,在\(n\)很小时,这个条件是必要的。

因此我们尝试证明这个条件是必要的。事实上,既然都写出搜索,我们就能发现在\(n=5\)时,这两种情况是可能的:

\[\begin{matrix}
-1 & 2 & -3 & 4 & 5 \\
1 & -2 & 3 & -4 & 5
\end{matrix}
\]

这意味着,只要先把所有元素移动到对应位置,就可以不断任取同奇偶的两列调整正负。因为奇偶性是保证的,所以一定能得到最终状态。所以本题标算搜索

时间复杂度\(O(n \log n)\)。

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int mat[4][N],val[N],n,num[2],v[N];
#define lowbit(x) ((x) & (-(x)))
void add(int p,int val) {
for ( ; p <= n ; p += lowbit(p))
v[p] += val;
}
int query(int p) {
int ret = 0;
for ( ; p ; p -= lowbit(p))
ret += v[p];
return ret;
}
void fail() {
puts("No");
exit(0);
}
int main() {
scanf("%d",&n);
for (int i = 1 ; i <= 3 ; ++ i)
for (int j = 1 ; j <= n ; ++ j)
scanf("%d",&mat[i][j]);
for (int i = 1 ; i <= n ; ++ i) {
if (mat[1][i] % 3 == 0) {
if (mat[2][i] == mat[1][i] - 1 && mat[3][i] == mat[1][i] - 2)
val[i] = - mat[1][i] / 3;
else fail();
} else if (mat[3][i] % 3 == 0) {
if (mat[2][i] == mat[3][i] - 1 && mat[1][i] == mat[3][i] - 2)
val[i] = mat[3][i] / 3;
else fail();
} else fail();
}
for (int i = 1 ; i <= n ; i += 2) {
if (val[i] < 0) num[1] ^= 1, val[i] = -val[i];
if (val[i] % 2 == 0) fail();
}
for (int i = 2 ; i <= n ; i += 2) {
if (val[i] < 0) num[0] ^= 1, val[i] = -val[i];
if (val[i]&1) fail();
}
for (int i = 1 ; i <= n ; i += 2) {
if ((query(n) - query(val[i]))&1) num[0] ^= 1;
add(val[i],1);
}
memset(v,0,sizeof v);
for (int i = 2 ; i <= n ; i += 2) {
if ((query(n) - query(val[i]))&1) num[1] ^= 1;
add(val[i],1);
}
if ((!num[0]) && (!num[1]))
puts("Yes");
else puts("No");
return 0;
}

小结:本题的解法主要有两点存在启发性:一是推导充分条件时,可以暂时放弃充分性来得到新的推论(这和求和时引入新的\(\sum\)有异曲同工之妙);二是一个搜索程序无伤大雅,除找规律乱搞外,还能成为解题的助力。

【做题】agc006e - Rotate 3x3——分析&思维的更多相关文章

  1. 2017国家集训队作业[agc006e]Rotate 3x3

    2017国家集训队作业[agc006e]Rotate 3x3 题意: ​ 给你一个\(3*N\)的网格,每次操作选择一个\(3*3\)的网格,旋转\(180^\circ\).问可不可以使每个位置\(( ...

  2. 【做题】CF177G2. Fibonacci Strings——思维+数列

    题意:定义斐波那契字符串为: $f_1 = $ "a" \(f_2 =\) "b" \(f_n = f_{n-1} + f_{n-2}, \, n > 2 ...

  3. 【做题】arc070_f-HonestOrUnkind——交互+巧妙思维

    做的第一道交互题-- 首先,有解的一个必要条件是\(a>b\).否则,即当\(a<=b\)时,可以有\(a\)个unkind的人假装自己就是那\(a\)个honest的人.(彼此之间都说是 ...

  4. [AGC006E] Rotate 3x3 树状数组+贪心

    Description ​ XFZ在北京一环内有一套房. ​ XFZ房子的地砖呈网格状分布,是一个3∗N3∗N的网格.XFZ在买下这套房时,每个地砖上有一个数字,位置为(i,j)(i,j)的地砖上的数 ...

  5. [agc006E]Rotate 3x3

    Description 给你一个3*N的网格,位置为(i,j)的网格上的数为i+3(j-1).每次选一个3*3的网格旋转180度,问最后能否使得网格(i,j)的值为ai,j.(5≤N≤105) 如图: ...

  6. AtCoder Grand Contest 1~10 做题小记

    原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-1-to-10.html 考虑到博客内容较多,编辑不方便的情 ...

  7. noip做题记录+挑战一句话题解?

    因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...

  8. 判断s2是否能够被通过s1做循环移位(rotate)得到的字符串是否包含

    问题:给定两个字符串s1和s2,要求判断s2是否能够被通过s1做循环移位(rotate)得到的字符串包含.例如,S1=AABCD和s2=CDAA,返回true:给定s1=ABCD和s2=ACBD,返回 ...

  9. C语言程序设计做题笔记之C语言基础知识(下)

    C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...

随机推荐

  1. JAVA SE ------------------- 项目的菜单输入

    //写一个工具类,进行输入选项数值的获取public class InputUtil { static Scanner sc=new Scanner(System.in); public static ...

  2. Luogu 1177 - 【模板】快速排序 - [快速排序][归并排序][无旋Treap]

    题目链接:https://www.luogu.org/problemnew/show/P1177 题意:输入 $n$ 以及后续 $n$ 个整数,让你将这 $n$ 个整数从小到大排序输出. 归并排序(用 ...

  3. vue里面的v-for列表循环

    列表渲染 v-for v-for可以把数据中的一个数组对应为一组元素v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名. ...

  4. 转 docker创建私有仓库和k8s中使用私有镜像

    docker私有仓库建立 环境说明我们选取192.168.5.2做私有仓库地址yum install docker -y1.启动docker仓库端口服务 docker run -d -p 5000:5 ...

  5. 部署WEB项目到服务器(二)安装tomcat到linux服务器(Ubuntu)详解

    突发奇想,想在自己电脑上部署一个web网站. 1,先去tomcat官网下载一个适合linux的版本:tar.gz 2,然后通过FileZIlla传到服务器的/opt目录: 3,然后创建目录 并解压缩 ...

  6. C++ 11 多线程下std::unique_lock与std::lock_guard的区别和用法

    这里主要介绍std::unique_lock与std::lock_guard的区别用法 先说简单的 一.std::lock_guard的用法 std::lock_guard其实就是简单的RAII封装, ...

  7. 斑马打印机ZT410中文打印

    ^XA ^CW1, E:SIMSUN.TTF^CI28^FO50,50^A1N,50,50^FD汉字^FS^XZ ******************************************* ...

  8. 16.4-uC/OS-III同步 (任务信号量)

    信号量和消息队列均是单独的内核对象,是独立于任务存在的. 任务信号量 仅发布给一个特定任务 .任务消息队列 可以发布给多个任务. 任务信号量伴随任务存在,只要创建了任务,其任务信号量就是该任务的一个数 ...

  9. DAX/PowerBI系列 - 参数表(Parameter Table) 度量值模板

    DAX/PowerBI系列 - 参数表(Parameter Table) 度量值模板 难度: ★★☆☆☆(2星) 适用范围: ★★★☆☆(3星) 概况: 当你有多个度量值都需要计算YTD,MoM,而又 ...

  10. centos----------centos下如何安装phpstorm

    1.首先打开centos下的谷歌浏览器,找到phpstorm官网下载linux版本.PhpStorm-2016.3.2.tar.gz 2.然后gunzip PhpStorm-2016.3.2.tar. ...