题目描述
这一次,L国决定军队分成n组,分布在各地,若以L国为原点,可以看作在一个直角坐标系内。但是他们都受统一的指挥,指令部共发出m个命令。命令有移动、上下转移和左右转移(瞬移??),但是由于某些奇奇怪怪的原因,军队收到命令总是有延迟,为了方便,军方已经写好一个栈(那还要我干嘛,自己都写好不就行了?),所以你要处理的顺序,应该是从后往前。
输入输出格式
输入格式:
输入文件army.in包括n+m+1行
第一行两个整数n、m
接下来n行
第i行有两个整数xi yi表示第i支军队的位置。
又是m行
每行首先是一个字符 C
若C为m 则紧跟两个整数 p q 表示把每支军队的位置从(xi,yi)移到(xi+p.yi+q)
若C为x 则表示把每支军队的位置从(xi,yi)移到(-xi,yi)
若C为y 则表示把每支军队的位置从(xi,yi)移到(xi,-yi)
输出格式:
输出文件army.out包含n行
第i行有两个整数xi、yi,表示第i支军队移动后的位置。
输入输出样例
3 3
0 0
4 -3
6 7
x
m -1 2
y
1 2
-3 5
-5 -5
说明
对于30%的数据 1≤n≤1000 1≤m≤1000
对于100%的数据 1≤n≤500000 1≤m≤500000 Ai在longint范围内
Solution:
本题矩阵乘法+模拟。
对于每个给定的坐标,一系列的变换是一致的,不难发现给定的三种操作都很适合用矩阵去构造。
所以我们可以对每种操作分别构建矩阵:
1. $(x,y)
ightarrow (-x,y)$:$egin{bmatrix}
-1& 0& 0\
0& 1& 0\
0& 0& 1
end{bmatrix}$
2.$(x,y)
ightarrow (x,-y)$:$egin{bmatrix}
1& 0& 0\
0& -1& 0\
0& 0& 1
end{bmatrix}$
3.$(x,y)
ightarrow (x+p,y+q)$:$egin{bmatrix}
1& 0& 0\
0& 1& 0\
p& q& 1
end{bmatrix}$
然后就是矩阵乘法搞出最后的转移矩阵(注意乘的过程是倒序),用初始矩阵$egin{bmatrix}
x_i & y_i & 1
end{bmatrix}$乘转移矩阵就是答案了。
代码:
/*Code by 520 -- 9.30*/ #include<bits/stdc++.h> #define il inline #define ll long long #define RE register #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++) #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--) #define clr(p) memset(&p,0,sizeof(p)) using namespace std; const int N=500005; ll n,m,X[N],Y[N]; struct matrix{ ll a[4][4],r,c; }op,t1,t2,t3; struct node{ ll opt,p,q; }t[N]; ll gi(){ ll a=0;char x=getchar();bool f=0; while((x<'0'||x>'9')&&x!='-') x=getchar(); if(x=='-') x=getchar(),f=1; while(x>='0'&&x<='9') a=(a<<3)+(a<<1)+(x^48),x=getchar(); return f?-a:a; } il matrix mul(matrix x,matrix y){ matrix tp;clr(tp); tp.r=x.r,tp.c=y.c; For(i,0,x.r-1) For(j,0,y.c-1) For(k,0,x.c-1) tp.a[i][j]+=x.a[i][k]*y.a[k][j]; return tp; } int main(){ n=gi(),m=gi(); For(i,1,n) X[i]=gi(),Y[i]=gi(); char s[2]; For(i,1,m) { scanf("%s",s); if(s[0]=='x') t[i].opt=1; if(s[0]=='y') t[i].opt=2; if(s[0]=='m') t[i].opt=3,t[i].p=gi(),t[i].q=gi(); } clr(op),clr(t1),clr(t2),clr(t3); op.r=op.c=3,t1.r=t1.c=3,t2.r=t2.c=3,t3.r=t3.c=3; t1.a[0][0]=-1,t1.a[1][1]=1,t1.a[2][2]=1,t2.a[0][0]=1,t2.a[1][1]=-1,t2.a[2][2]=1; op.a[0][0]=op.a[1][1]=op.a[2][2]=1; Bor(i,1,m) { if(t[i].opt==1) op=mul(op,t1); else if(t[i].opt==2) op=mul(op,t2); else { t3.a[0][0]=1,t3.a[1][1]=1,t3.a[2][0]=t[i].p,t3.a[2][1]=t[i].q,t3.a[2][2]=1; op=mul(op,t3); } } matrix ans;clr(ans);ans.r=1,ans.c=3; For(i,1,n) { ans.a[0][0]=X[i],ans.a[0][1]=Y[i],ans.a[0][2]=1; ans=mul(ans,op); printf("%lld %lld ",ans.a[0][0],ans.a[0][1]); } return 0; }