結果
| 問題 |
No.1226 I hate Robot Arms
|
| コンテスト | |
| ユーザー |
🍮かんプリン
|
| 提出日時 | 2020-09-12 00:01:33 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 7,633 bytes |
| コンパイル時間 | 1,929 ms |
| コンパイル使用メモリ | 180,880 KB |
| 実行使用メモリ | 88,520 KB |
| 最終ジャッジ日時 | 2025-01-01 22:52:04 |
| 合計ジャッジ時間 | 43,651 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 18 TLE * 10 |
ソースコード
/**
* @FileName a.cpp
* @Author kanpurin
* @Created 2020.09.12 00:01:28
**/
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template < class Monoid >
struct SegmentTree {
private:
using Func = std::function< Monoid(Monoid, Monoid) >;
Func F;
Monoid UNITY;
int n;
std::vector< Monoid > node;
public:
SegmentTree() {}
SegmentTree(const std::vector< Monoid > &v, const Func f, const Monoid &unity) {
F = f;
UNITY = unity;
int sz = v.size();
n = 1;
while (n < sz) n <<= 1;
node.resize(n * 2 - 1, UNITY);
for (int i = 0; i < sz; i++) node[i + n - 1] = v[i];
build();
}
SegmentTree(int m, const Monoid &val, const Func f, const Monoid &unity) {
F = f;
UNITY = unity;
n = 1;
while (n < m) n <<= 1;
node.resize(n * 2 - 1, UNITY);
if (val != UNITY) {
for (int i = 0; i < m; i++) node[i + n - 1] = val;
build();
}
}
void set(int k, const Monoid &x) {
node[n + k - 1] = x;
}
void build() {
for (int i = n - 2; i >= 0; i--) node[i] = F(node[2 * i + 1], node[2 * i + 2]);
}
void update_query(int x, const Monoid &val) {
if (x >= n || x < 0) return;
x += n - 1;
node[x] = val;
while (x > 0) {
x = (x - 1) >> 1;
node[x] = F(node[2 * x + 1], node[2 * x + 2]);
}
}
/*
Monoid query(int a, int b, int k = 0, int l = 0, int r = -1) {
if (r < 0) r = n;
if (r <= a || b <= l) return UNITY;
if (a <= l && r <= b) return node[k];
Monoid vl = query(a, b, 2 * k + 1, l, (r - l) / 2 + l);
Monoid vr = query(a, b, 2 * k + 2, (r - l) / 2 + l, r);
return F(vl, vr);
}
*/
Monoid get_query(int a, int b) {
Monoid L = UNITY, R = UNITY;
if (a < 0) a = 0;
if (b < 0) return UNITY;
if (a >= n) return UNITY;
if (b >= n) b = n;
for (a += n, b += n; a < b; a >>= 1, b >>= 1) {
if (a & 1) L = F(L, node[a++ - 1]);
if (b & 1) R = F(node[--b - 1], R);
}
return F(L, R);
}
Monoid operator[](int x) const {
return node[n + x - 1];
}
int size() {
return n;
}
void print() {
for (int i = 0; i < n; i++) {
std::cout << i << "\t: " << node[n + i - 1] << std::endl;
}
}
};
template< class T >
struct Matrix {
std::vector< std::vector< T > > A;
Matrix() {}
Matrix(size_t n, size_t m) : A(n, std::vector< T >(m, 0)) {}
Matrix(size_t n) : A(n, std::vector< T >(n, 0)) {};
size_t height() const {
return (A.size());
}
size_t width() const {
return (A[0].size());
}
inline const std::vector< T > &operator[](int k) const {
return (A.at(k));
}
inline std::vector< T > &operator[](int k) {
return (A.at(k));
}
static Matrix I(size_t n) {
Matrix mat(n);
for (int i = 0; i < n; i++) mat[i][i] = 1;
return (mat);
}
Matrix &operator+=(const Matrix &B) {
size_t n = height(), m = width();
assert(n == B.height() && m == B.width());
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) {
size_t n = height(), m = width();
assert(n == B.height() && m == B.width());
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) {
size_t n = height(), m = B.width(), p = width();
assert(p == B.height());
std::vector< std::vector< T > > C(n, std::vector< T >(m, 0));
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
for (int k = 0; k < p; k++)
C[i][j] = (C[i][j] + (*this)[i][k] * B[k][j]);
A.swap(C);
return (*this);
}
Matrix operator+(const Matrix &B) const {
return (Matrix(*this) += B);
}
Matrix operator-(const Matrix &B) const {
return (Matrix(*this) -= B);
}
Matrix operator*(const Matrix &B) const {
return (Matrix(*this) *= B);
}
bool operator==(const Matrix &B) const {
assert(this->A.size() == B.A.size() && this->A[0].size() == B.A[0].size());
int n = this->A.size();
int m = this->A[0].size();
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (this->A[i][j] != B.A[i][j]) return false;
return true;
}
bool operator!=(const Matrix &B) const {
return !(*this == B);
}
friend std::ostream &operator<<(std::ostream &os, Matrix &p) {
size_t n = p.height(), m = p.width();
for (int i = 0; i < n; i++) {
os << "[";
for (int j = 0; j < m; j++) {
os << p[i][j] << (j + 1 == m ? "]\n" : ",");
}
}
return (os);
}
T determinant() {
Matrix B(*this);
assert(width() == height());
T ret = 1;
for (int i = 0; i < width(); i++) {
int idx = -1;
for (int j = i; j < width(); j++) {
if (B[j][i] != 0) idx = j;
}
if (idx == -1) return (0);
if (i != idx) {
ret *= -1;
swap(B[i], B[idx]);
}
ret *= B[i][i];
T vv = B[i][i];
for (int j = 0; j < width(); j++) {
B[i][j] /= vv;
}
for (int j = i + 1; j < width(); j++) {
T a = B[j][i];
for (int k = 0; k < width(); k++) {
B[j][k] -= B[i][k] * a;
}
}
}
return (ret);
}
Matrix pow(ll k) const {
auto res = I(A.size());
auto M = *this;
while (k > 0) {
if (k & 1) {
res *= M;
}
M *= M;
k >>= 1;
}
return res;
}
};
#define MAT Matrix<double>
int main() {
int n,q;cin >> n >> q;
MAT init(4);
init[0][0] = init[1][1] = init[2][2] = init[3][3] = 1;
init[0][2] = init[1][3] = 1;
SegmentTree<MAT> seg(n,init,[](MAT a,MAT b){return b*a;},MAT::I(4));
const double PI = 3.141592653589;
vector<int> d(n,1), sita(n,0);
while(q--) {
int t;cin >> t;
if (t == 0) {
int i,x;cin >> i >> x;
auto mat = seg.get_query(i-1,i);
sita[i-1] = x;
mat[2][2] = mat[3][3] = cos(x/180.0*PI);
mat[3][2] = sin(x/180.0*PI);
mat[2][3] = -mat[3][2];
mat[0][2] = mat[1][3] = d[i-1]*cos(sita[i-1]/180.0*PI);
mat[1][2] = d[i-1]*sin(sita[i-1]/180.0*PI);
mat[0][3] = -mat[1][2];
seg.update_query(i-1,mat);
}
else if (t == 1) {
int i,x;cin >> i >> x;
auto mat = seg.get_query(i-1,i);
d[i-1] = x;
mat[0][2] = mat[1][3] = d[i-1]*cos(sita[i-1]/180.0*PI);
mat[1][2] = d[i-1]*sin(sita[i-1]/180.0*PI);
mat[0][3] = -mat[1][2];
seg.update_query(i-1,mat);
}
else {
int i;cin >> i;
auto ans = seg.get_query(0,i);
printf("%.10f %.10f\n",ans[0][2],ans[1][2]);
}
}
return 0;
}
🍮かんプリン