1. 程式人生 > >P2129 L國的戰鬥續之多路出擊

P2129 L國的戰鬥續之多路出擊

題目描述

這一次,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支軍隊移動後的位置。

輸入輸出樣例

輸入樣例#1: 
3 3
0 0
4 -3
6 7
x
m -1 2
y
輸出樣例#1: 
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)\rightarrow (-x,y)$:$\begin{bmatrix}
 -1&  0& 0\\
 0&  1& 0\\
 0&  0& 1
\end{bmatrix}$

  2.$(x,y)\rightarrow (x,-y)$:$\begin{bmatrix}
 1&  0& 0\\
 0&  -1& 0\\
 0&  0& 1
\end{bmatrix}$

  3.$(x,y)\rightarrow (x+p,y+q)$:$\begin{bmatrix}
 1&  0& 0\\
 0&  1& 0\\
 p&  q& 1
\end{bmatrix}$

  然後就是矩陣乘法搞出最後的轉移矩陣(注意乘的過程是倒序),用初始矩陣$\begin{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\n",ans.a[0][0],ans.a[0][1]);
    }
    return 0;
}