题目链接
题目大意
给你n个点你对这n个点进行m次操作
操作有四种
第一种使得所有点nx=y ny=-x
第二种使得所有点nx=-y ny=x
第三种使得所有点nx=2p-x ny=y
第四种使得所有点nx=x ny=2p-y
有q次查询
每次查询为b位置经过a次操作后的坐标
题目思路
这个就是每个位置都和以前的位置有关就要想到矩阵操作
把它转化为矩阵的操作即可
第一种操作
[egin{pmatrix} 0& 1&0 \ -1 & 0 &0\ 0&0&1 end{pmatrix}
]
第二种操作
[egin{pmatrix} 0& -1&0 \ 1 & 0 &0\ 0&0&1 end{pmatrix}
]
第三种操作
[egin{pmatrix} -1& 0&2p \ 0 & 1 &0 \ 0&0&1 end{pmatrix}
]
第四种操作
[egin{pmatrix} 1& 0&0 \ 0 & -1 &2p\ 0&0&1 end{pmatrix}
]
注意相乘为(pre[i]=mul(basei,pre[i-1])) 注意顺序
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=998244353;
const int eps=1e-6;
int n,m,q;
int x[maxn],y[maxn];
struct matrix{
ll a[4][4];
}base1,base2,base3,base4,pre[maxn];
void init(){
pre[0].a[1][1]=pre[0].a[2][2]=pre[0].a[3][3]=1;
base1.a[1][2]=base1.a[3][3]=1;
base1.a[2][1]=-1;
base2.a[1][2]=-1;
base2.a[2][1]=base2.a[3][3]=1;
base3.a[1][1]=-1;
base3.a[2][2]=base3.a[3][3]=1; //a[1][3] =2p
base4.a[1][1]=base4.a[3][3]=1;
base4.a[2][2]=-1; //a[2][3]=2p
}
matrix mul(matrix a,matrix b){
matrix ans;
memset(ans.a,0,sizeof(ans.a));
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++){
for(int k=1;k<=3;k++){
ans.a[i][k]+=a.a[i][j]*b.a[j][k];
}
}
}
return ans;
}
signed main(){
init();
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&x[i],&y[i]);
}
scanf("%d",&m);
for(int i=1,opt,p;i<=m;i++){
scanf("%d",&opt);
if(opt==1){
pre[i]=mul(base1,pre[i-1]);
}else if(opt==2){
pre[i]=mul(base2,pre[i-1]);
}else if(opt==3){
scanf("%d",&p);
base3.a[1][3]=2*p;
pre[i]=mul(base3,pre[i-1]);
}else if(opt==4){
scanf("%d",&p);
base4.a[2][3]=2*p;
pre[i]=mul(base4,pre[i-1]);
}
}
scanf("%d",&q);
for(int i=1,a,b;i<=q;i++){
scanf("%d%d",&a,&b);
ll prx=pre[a].a[1][1]*x[b]+pre[a].a[1][2]*y[b]+pre[a].a[1][3]*1;
ll pry=pre[a].a[2][1]*x[b]+pre[a].a[2][2]*y[b]+pre[a].a[2][3]*1;
printf("%lld %lld
",prx,pry);
}
return 0;
}