生活随笔
收集整理的這篇文章主要介紹了
ABC 189 E - Rotate and Flip 矩阵转移
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
傳送門(mén)
題意:給定n個(gè)點(diǎn),m個(gè)操作,n和m都是1e5級(jí)別的。讓后每個(gè)操作是將這個(gè)點(diǎn)繞原點(diǎn)順時(shí)針、逆時(shí)針轉(zhuǎn)90°,將這個(gè)點(diǎn)按照 x = p 或著 y = p 做對(duì)稱。再有q個(gè)詢問(wèn),q也是1e5級(jí)別的。讓后每個(gè)詢問(wèn)是問(wèn)B這個(gè)點(diǎn)在第A次操作之后在哪里。
顯然我們不能直接暴力,因?yàn)槎歼_(dá)到了1e5級(jí)別。 一開(kāi)始像找一下規(guī)律,看看是否這幾個(gè)操作是相互獨(dú)立的,一開(kāi)始發(fā)現(xiàn)了點(diǎn),但是隨著越來(lái)越多的例子,很快否定了我找規(guī)律的想法。 現(xiàn)在問(wèn)題就是我們能否將點(diǎn)的變換轉(zhuǎn)變成類似乘法除法之類可以累計(jì)的變量呢?顯然就會(huì)發(fā)現(xiàn)矩陣是滿足這個(gè)性質(zhì)的,我們只需要對(duì)每個(gè)操作遞推維護(hù)一個(gè)右乘矩陣,當(dāng)需要進(jìn)行前A次操作的時(shí)候只需要乘一下A這個(gè)操作之前的矩陣乘積即可。 下面依次給出這幾個(gè)操作的矩陣。 當(dāng)然為了方便我們可以把初始矩陣寫(xiě)成 (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} ? ? ? 0 1 0 ? ? 1 0 0 ? 0 0 1 ? ? ? ? (010?100001)\begin{pmatrix} 0 & 1 & 0 \\ -1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix} ? ? ? 0 ? 1 0 ? 1 0 0 ? 0 0 1 ? ? ? ? (?1000102p01)\begin{pmatrix} -1 & 0 & 0 \\ 0 & 1 & 0 \\ 2p & 0 & 1 \end{pmatrix} ? ? ? ? 1 0 2 p ? 0 1 0 ? 0 0 1 ? ? ? ? (1000?1002p1)\begin{pmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & 2p &1 \end{pmatrix} ? ? ? 1 0 0 ? 0 ? 1 2 p ? 0 0 1 ? ? ? ? 為什么多加了一維呢?想必看到上面矩陣的時(shí)候大家也知道了,因?yàn)閷?duì)稱的時(shí)候會(huì)多一個(gè)常數(shù),所以加一維比較方便處理常數(shù)。 下面代碼僅供參考,寫(xiě)的比較亂
#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
;
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 ( )
{
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 ;
}
總結(jié)
以上是生活随笔 為你收集整理的ABC 189 E - Rotate and Flip 矩阵转移 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。