Submission #35374154
Source Code Expand
#include <bits/stdc++.h>
using namespace std;
#ifdef _RUTHEN
#include <debug.hpp>
#else
#define show(...) true
#endif
using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); i++)
template <class T> using V = vector<T>;
template <class T> struct matrix {
std::vector<std::vector<T>> A;
matrix(int N) : A(N, std::vector<T>(N, T(0))) {}
matrix(int N, int M, T val = T(0)) : A(N, std::vector<T>(M, val)) {}
size_t size() const { return A.size(); }
int row() const { return (int)A.size(); }
int col() const { return (int)A[0].size(); }
inline const std::vector<T> &operator[](int i) const { return A[i]; } // read
inline std::vector<T> &operator[](int i) { return A[i]; } // write
static matrix E(int N) {
matrix ret(N);
for (int i = 0; i < N; i++) ret[i][i] = T(1);
return ret;
}
matrix &operator+=(const matrix &B) {
int N = row(), M = col();
assert(N == B.row() && M == B.col());
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
(*this)[i][j] += B[i][j];
}
}
return (*this);
}
matrix &operator-=(const matrix &B) {
int N = row(), M = col();
assert(N == B.row() && M == B.col());
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
(*this)[i][j] -= B[i][j];
}
}
return (*this);
}
matrix &operator*=(const matrix &B) {
int N = row(), M = B.col(), L = B.row();
assert(L == col());
matrix C(N, M);
for (int i = 0; i < N; i++) {
for (int k = 0; k < L; k++) {
for (int j = 0; j < M; j++) {
C[i][j] += (*this)[i][k] * B[k][j];
}
}
}
A.swap(C.A);
return (*this);
}
matrix pow(long long n) {
assert(row() == col());
matrix B = matrix::E(row()), X = (*this);
while (n) {
if (n & 1) B *= X;
X *= X;
n >>= 1;
}
A.swap(B.A);
return (*this);
}
matrix operator+(const matrix &B) { return ((*this) += B); }
matrix operator-(const matrix &B) { return ((*this) -= B); }
matrix operator*(const matrix &B) { return ((*this) *= B); }
friend std::ostream &operator<<(std::ostream &os, matrix &A) {
int N = A.row(), M = A.col();
for (int i = 0; i < N; i++) {
os << '[';
for (int j = 0; j < M; j++) os << A[i][j] << " \n"[j == M - 1];
}
return (os);
}
matrix &operator+=(const T &k) {
int N = row(), M = col();
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++) (*this)[i][j] += k;
return (*this);
}
matrix &operator-=(const T &k) {
int N = row(), M = col();
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++) (*this)[i][j] -= k;
return (*this);
}
matrix &operator*=(const T &k) {
int N = row(), M = col();
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++) (*this)[i][j] *= k;
return (*this);
}
matrix &operator/=(const T &k) {
int N = row(), M = col();
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++) (*this)[i][j] /= k;
return (*this);
}
matrix operator+(const T &k) { return ((*this) += k); }
matrix operator-(const T &k) { return ((*this) -= k); }
matrix operator*(const T &k) { return ((*this) *= k); }
matrix operator/(const T &k) { return ((*this) /= k); }
};
/**
* @brief Matrix (行列)
*/
template <class Monoid> struct segment_tree {
public:
using S = typename Monoid::value_type;
segment_tree() : segment_tree(0) {}
segment_tree(int n) : segment_tree(std::vector<S>(n, Monoid::e())) {}
segment_tree(const std::vector<S>& v) : _n((int)v.size()) {
log = 0;
while ((1U << log) < (unsigned int)(_n)) log++;
size = 1 << log;
d = std::vector<S>(size << 1, Monoid::e());
for (int i = 0; i < _n; i++) d[i + size] = v[i];
for (int i = size - 1; i >= 1; i--) {
update(i);
}
}
void set(int p, const S& x) {
assert(0 <= p and p < _n);
p += size;
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
void chset(int p, const S& x) {
assert(0 <= p and p < _n);
p += size;
d[p] = Monoid::op(d[p], x);
for (int i = 1; i <= log; i++) update(p >> i);
}
S operator[](int p) const {
assert(0 <= p and p < _n);
return d[p + size];
}
S get(int p) const {
assert(0 <= p && p < _n);
return d[p + size];
}
S prod(int l, int r) const {
assert(0 <= l and l <= r and r <= _n);
S sml = Monoid::e(), smr = Monoid::e();
l += size;
r += size;
while (l < r) {
if (l & 1) sml = Monoid::op(sml, d[l++]);
if (r & 1) smr = Monoid::op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return Monoid::op(sml, smr);
}
S all_prod() const { return d[1]; }
template <class F> int max_right(int l, F& f) const {
assert(0 <= l and l <= _n);
assert(f(Monoid::e()));
if (l == _n) return _n;
l += size;
S sm = Monoid::e();
do {
while ((l & 1) == 0) l >>= 1;
if (!f(Monoid::op(sm, d[l]))) {
while (l < size) {
l <<= 1;
if (f(Monoid::op(sm, d[l]))) {
sm = Monoid::op(sm, d[l]);
l++;
}
}
return l - size;
}
sm = Monoid::op(sm, d[l]);
l++;
} while ((l & -l) != l); // 2べきまたは0のときfalse
return _n;
}
template <class F> int min_left(int r, F& f) const {
assert(0 <= r and r <= _n);
assert(f(Monoid::e()));
if (r == 0) return 0;
r += size;
S sm = Monoid::e();
do {
r--;
while (r > 1 and (r & 1)) r >>= 1;
if (!f(Monoid::op(d[r], sm))) {
while (r < size) {
r = (r << 1) | 1;
if (f(Monoid::op(d[r], sm))) {
sm = Monoid::op(d[r], sm);
r--;
}
}
return r + 1 - size;
}
sm = Monoid::op(d[r], sm);
} while ((r & -r) != r); // 2べきまたは0のときfalse
return 0;
}
private:
int _n, log, size;
std::vector<S> d;
inline void update(int k) { d[k] = Monoid::op(d[k << 1], d[(k << 1) | 1]); }
};
/**
* @brief Segment Tree (セグメント木)
* @docs docs/data_structure/segment_tree.md
*/
// #include "src/data_structure/static_matrix.hpp"
template <class S> struct monoid {
using value_type = S;
static const S op(S a, S b) { return b * a; }
static const S e() { return S::E(3); }
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int N;
cin >> N;
V<ll> X(N), Y(N);
rep(i, N) cin >> X[i] >> Y[i];
int M;
cin >> M;
V<matrix<ll>> A(M, matrix<ll>(3));
rep(i, M) {
int t;
cin >> t;
if (t == 1) {
A[i][0][1] = 1;
A[i][1][0] = -1;
} else if (t == 2) {
A[i][0][1] = -1;
A[i][1][0] = 1;
} else if (t == 3) {
int p;
cin >> p;
A[i][0][0] = -1;
A[i][1][1] = 1;
A[i][0][2] = 2 * p;
} else {
int p;
cin >> p;
A[i][0][0] = 1;
A[i][1][1] = -1;
A[i][1][2] = 2 * p;
}
A[i][2][2] = 1;
}
segment_tree<monoid<matrix<ll>>> seg(A);
int Q;
cin >> Q;
while (Q--) {
int r, i;
cin >> r >> i;
i--;
auto af = seg.prod(0, r);
ll ansx = af[0][0] * X[i] + af[0][1] * Y[i] + af[0][2];
ll ansy = af[1][0] * X[i] + af[1][1] * Y[i] + af[1][2];
cout << ansx << ' ' << ansy << '\n';
}
return 0;
}
Submission Info
Submission Time |
|
Task |
E - Rotate and Flip |
User |
ruthen71 |
Language |
C++ (GCC 9.2.1) |
Score |
500 |
Code Size |
8643 Byte |
Status |
AC |
Exec Time |
1200 ms |
Memory |
150548 KiB |
Judge Result
Set Name |
Sample |
All |
Score / Max Score |
0 / 0 |
500 / 500 |
Status |
|
|
Set Name |
Test Cases |
Sample |
sample_01.txt, sample_02.txt |
All |
max_01.txt, max_02.txt, max_03.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, random_21.txt, random_22.txt, random_23.txt, sample_01.txt, sample_02.txt |
Case Name |
Status |
Exec Time |
Memory |
max_01.txt |
AC |
1067 ms |
150416 KiB |
max_02.txt |
AC |
875 ms |
150548 KiB |
max_03.txt |
AC |
294 ms |
144672 KiB |
random_01.txt |
AC |
3 ms |
3744 KiB |
random_02.txt |
AC |
3 ms |
3704 KiB |
random_03.txt |
AC |
2 ms |
3676 KiB |
random_04.txt |
AC |
2 ms |
3596 KiB |
random_05.txt |
AC |
4 ms |
3676 KiB |
random_06.txt |
AC |
2 ms |
3668 KiB |
random_07.txt |
AC |
3 ms |
3684 KiB |
random_08.txt |
AC |
2 ms |
3680 KiB |
random_09.txt |
AC |
5 ms |
3712 KiB |
random_10.txt |
AC |
2 ms |
3692 KiB |
random_11.txt |
AC |
2 ms |
3668 KiB |
random_12.txt |
AC |
2 ms |
3720 KiB |
random_13.txt |
AC |
2 ms |
3748 KiB |
random_14.txt |
AC |
3 ms |
3696 KiB |
random_15.txt |
AC |
2 ms |
3708 KiB |
random_16.txt |
AC |
2 ms |
3748 KiB |
random_17.txt |
AC |
2 ms |
3512 KiB |
random_18.txt |
AC |
2 ms |
3568 KiB |
random_19.txt |
AC |
3 ms |
3676 KiB |
random_20.txt |
AC |
2 ms |
3600 KiB |
random_21.txt |
AC |
568 ms |
75532 KiB |
random_22.txt |
AC |
1200 ms |
150540 KiB |
random_23.txt |
AC |
1200 ms |
150544 KiB |
sample_01.txt |
AC |
9 ms |
3604 KiB |
sample_02.txt |
AC |
2 ms |
3636 KiB |