传送门

题意:给定n个点,m个操作,n和m都是1e5级别的。让后每个操作是将这个点绕原点顺时针、逆时针转90°,将这个点按照 x = p 或着 y = p 做对称。再有q个询问,q也是1e5级别的。让后每个询问是问B这个点在第A次操作之后在哪里。

显然我们不能直接暴力,因为都达到了1e5级别。
一开始像找一下规律,看看是否这几个操作是相互独立的,一开始发现了点,但是随着越来越多的例子,很快否定了我找规律的想法。
现在问题就是我们能否将点的变换转变成类似乘法除法之类可以累计的变量呢?显然就会发现矩阵是满足这个性质的,我们只需要对每个操作递推维护一个右乘矩阵,当需要进行前A次操作的时候只需要乘一下A这个操作之前的矩阵乘积即可。
下面依次给出这几个操作的矩阵。
当然为了方便我们可以把初始矩阵写成
(xy1)\begin{pmatrix} x & y & 1\\ \end{pmatrix} (x​y​1​)
(0−10100001)\begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix} ⎝⎛​010​−100​001​⎠⎞​
(010−100001)\begin{pmatrix} 0 & 1 & 0 \\ -1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix} ⎝⎛​0−10​100​001​⎠⎞​
(−1000102p01)\begin{pmatrix} -1 & 0 & 0 \\ 0 & 1 & 0 \\ 2p & 0 & 1 \end{pmatrix} ⎝⎛​−102p​010​001​⎠⎞​
(1000−1002p1)\begin{pmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & 2p &1 \end{pmatrix} ⎝⎛​100​0−12p​001​⎠⎞​
为什么多加了一维呢?想必看到上面矩阵的时候大家也知道了,因为对称的时候会多一个常数,所以加一维比较方便处理常数。
下面代码仅供参考,写的比较乱

//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n,m;
struct Point
{int x,y;
}q[N];
struct Query
{LL mp[3][3];
}node[N],t;
vector<Query>v;void mult(int id,Query v,int op)
{int x;if(op==3||op==4) scanf("%d",&x);if(op==3) v.mp[2][0]=2*x;else if(op==4) v.mp[2][1]=2*x;for(int i=0;i<3;i++)for(int j=0;j<3;j++)for(int k=0;k<3;k++)node[id+1].mp[i][j]+=node[id].mp[i][k]*v.mp[k][j];
}int main()
{//  ios::sync_with_stdio(false);
//  cin.tie(0);t.mp[0][0]=0; t.mp[0][1]=-1; t.mp[0][2]=0;t.mp[1][0]=1; t.mp[1][1]=0; t.mp[1][2]=0;t.mp[2][0]=0; t.mp[2][1]=0; t.mp[2][2]=1;v.push_back(t);t.mp[0][0]=0; t.mp[0][1]=1; t.mp[0][2]=0;t.mp[1][0]=-1; t.mp[1][1]=0; t.mp[1][2]=0;t.mp[2][0]=0; t.mp[2][1]=0; t.mp[2][2]=1;v.push_back(t);t.mp[0][0]=-1; t.mp[0][1]=0; t.mp[0][2]=0;t.mp[1][0]=0; t.mp[1][1]=1; t.mp[1][2]=0;t.mp[2][0]=0; t.mp[2][1]=0; t.mp[2][2]=1;v.push_back(t);t.mp[0][0]=1; t.mp[0][1]=0; t.mp[0][2]=0;t.mp[1][0]=0; t.mp[1][1]=-1; t.mp[1][2]=0;t.mp[2][0]=0; t.mp[2][1]=0; t.mp[2][2]=1;v.push_back(t);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d%d",&q[i].x,&q[i].y);scanf("%d",&m);node[0].mp[0][0]=node[0].mp[1][1]=node[0].mp[2][2]=1;for(int i=1;i<=m;i++){int op; scanf("%d",&op);mult(i-1,v[op-1],op);}int _; scanf("%d",&_);while(_--){int a,b; scanf("%d%d",&a,&b);Query t,ans;memset(t.mp,0,sizeof(t.mp));memset(ans.mp,0,sizeof(ans.mp));t.mp[0][0]=q[b].x,t.mp[0][1]=q[b].y,t.mp[0][2]=1;for(int i=0;i<3;i++)for(int j=0;j<3;j++)for(int k=0;k<3;k++)ans.mp[i][j]+=t.mp[i][k]*node[a].mp[k][j];printf("%lld %lld\n",ans.mp[0][0],ans.mp[0][1]);}return 0;
}
/**/

ABC 189 E - Rotate and Flip 矩阵转移相关推荐

  1. E - Rotate and Flip(线性代数矩阵坐标变换)

    E - Rotate and Flip 顺时针 [010−100001][xy1]=[y−x1]\begin{bmatrix} 0 & 1 & 0\\ -1&0&0\\ ...

  2. E - Rotate and Flip(转化一般性)

    E - Rotate and Flip 对于有n个点,m个变换(包括旋转90度和关于某条直线对称),q次询问ai点在bi个变换后的坐标. 显然对于这些变换我们都是能够直接利用公式求解的,所以我们直接用 ...

  3. 9.leetcode题目189: Rotate Array

    这道题一直做不好.. Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, ...

  4. OpenCv图像处理之resize(缩放)、transpose、rotate(旋转)、flip(翻转)介绍

    OpenCv图像处理之resize.transpose.rotate.flip介绍 cv::resize操作 cv::transpose操作 cv::rotate操作 cv::flip操作 cv::r ...

  5. Mat矩阵基本操作与示例 OpenCV

    OpenCV的基本矩阵操作与示例 OpenCV中的矩阵操作非常重要,本文总结了矩阵的创建.初始化以及基本矩阵操作,给出了示例代码,主要内容包括: 创建与初始化 矩阵加减法 矩阵乘法 矩阵转置 矩阵求逆 ...

  6. HDU - 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)

    题目链接:点击查看 题目大意:给出 n 个词根,现在要求出长度不大于 len 的单词中,有多少单词包含至少一个词根 题目分析:如果我们反过来想,也就是求出来总的单词数,然后减去不包含词根的单词数,剩下 ...

  7. jzoj6293-迷宫【ddp,线段树,矩阵乘法】

    正题 题目大意 一个n∗mn*mn∗m的迷宫,不能往左走,有墙,每次修改一个点或询问两个点之间的最短距离. 解题思路 考虑到nnn的值很小,所以我们可以用矩阵转移,然后要求支持修改和查询所以我们考虑d ...

  8. opencv简单的矩阵操作

    OpenCV的基本矩阵操作与示例 OpenCV中的矩阵操作非常重要,本文总结了矩阵的创建.初始化以及基本矩阵操作,给出了示例代码,主要内容包括: 创建与初始化 矩阵加减法 矩阵乘法 矩阵转置 矩阵求逆 ...

  9. OpenCV中对数组(矩阵)的常用操作

          add 矩阵加法,A+B的更高级形式,支持mask scaleAdd 矩阵加法,一个带有缩放因子dst(I) = scale * src1(I) + src2(I) addWeighted ...

最新文章

  1. Android -- EventBus使用
  2. DirectX11 driver类型浅析
  3. Windows 1.0 to Windows 10
  4. 概率论 第四章 随机变量的数字特征
  5. 深度学习:背景建模高斯混合模型
  6. 计算机硬件假故障,计算机硬件故障
  7. 十一届蓝桥杯国赛 美丽的2-枚举
  8. css background size
  9. 算法(28)--矩阵搜索系列
  10. stm32双向可控硅调压程序_双向可控硅的工作原理
  11. 美国知名天使投资人列出愿意投资的30大创意方向
  12. 病毒详解及批处理病毒制作:自启动、修改密码、定时关机、蓝屏、进程关闭...
  13. LeaRun敏捷开发框架快速设计表单
  14. polkitd进程解释
  15. 仙境传说 第一章之四 卢渊*梦魇过后的情缘
  16. android应用开发-从设计到实现 2-4 文字的使用
  17. zigbee菜鸟笔记(一)zigbee的基础知识
  18. 微信小程序——VW、VH
  19. 19.1 快速幂的定义和模板
  20. STM32F1XX的GPIO的8种工作模式以及GPIO的寄存器简介

热门文章

  1. 花季少女竟然有个三年级老公??!
  2. 女朋友在家是怎么利用我的模型的​
  3. 厉害了!这几位小学生竟然在艺术界掀起一阵风暴,简直是灵魂画手无疑.........
  4. Jupyter 常见可视化框架的选择
  5. linux浏览器不能播放音频文件夹,在html中插入音频文件在浏览器中播放音频文件的兼容性问题...
  6. sql两个列值以下划线拼接得到一个新的列_面试必备sql知识点——MySQL基础
  7. 仓库每天的账怎样做_新年第一站,济南:仓储匠人仓库问题解决与实战力培训...
  8. linux改环境语言,linux下改变语言环境
  9. linux ll 转数组,List、Set、数组之间的转换
  10. c语言怎么让图形界面单独显示,「分享」C语言如何编写图形界面