原来写矩阵线段树没问题。改成虚数就 WA 了
但是样例过了。感觉是虚数库的问题。
有没有路过大佬帮忙看看?
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define rep(i, a, b) for (int i = (a); i <= (b); i ++ )
#define rop(i, a, b) for (int i = (a); i < (b); i ++ )
#define dep(i, a, b) for (int i = (a); i >= (b); i -- )
#define dop(i, a, b) for (int i = (a); i > (b); i -- )
using namespace std;
using LL = long long;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
namespace FastIO {
char buf[1 << 20], *_now = buf, *_end = buf;
#define getchar() (_now == _end && (_end = (_now = buf) + fread(buf, 1, 1 << 10, stdin), _now == _end) ? EOF : *_now ++ )
void read() { return; }
template <typename T, typename ...T2>
void read(T &s, T2 &...oth) {
s = 0; int f = 1; char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = ~f + 1;
for (; ch >= '0' && ch <= '9'; ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48);
s *= f; read(oth...); return;
}
void write() { return; }
template <typename T, typename ...T2>
void write(T s, T2 ...oth) {
int stk[100], top = 0;
if (s < 0) putchar('-'), s = ~s + 1;
while (s) stk[ ++ top] = s % 10, s /= 10;
do putchar(stk[top -- ] + (1 << 4) + (1 << 5)); while (top);
putchar('\n'); write(oth...); return;
}
}
#define read FastIO::read
#define write FastIO::write
#define Inline inline
const int N = 300010;
const double pi = acos(-1);
double Sin[360], Cos[360];
int n, m;
PII p[N];
struct Complex {
double x, y;
Complex(){}
Complex(int _x, int _y) { x = _x, y = _y; }
Complex operator + (const Complex& tmp)const {
return Complex(x + tmp.x, y + tmp.y);
}
Complex operator * (const Complex& tmp)const {
return Complex(x * tmp.y + y * tmp.x, y * tmp.y - x * tmp.x);
}
Complex operator - (const Complex& tmp)const {
return Complex(x - tmp.x, y - tmp.y);
}
Complex operator * (const double &tmp)const {
return Complex(this -> x * tmp, this -> y * tmp);
}
// Complex &operator += (Complex& tmp) {
// *this = (*this + tmp);
// return *this;
// }
// Complex &operator *= (Complex& tmp) {
// *this = (*this * tmp);
// return *this;
// }
void clear() { x = y = 0; }
void makeI() { x = 0, y = 1; }
bool empty() { return (x == 0) and (y == 0); }
bool isI() { return (x == 0) && (y == 1); }
};
struct Tree {
int l, r;
Complex add, mul;
Complex sum;
int len() { return r - l + 1; }
}tr[N << 2];
#define ls u << 1
#define rs u << 1 | 1
void pushup(int u) {
tr[u].sum = tr[ls].sum + tr[rs].sum;
}
void push_add(int u, Complex add) {
if (tr[u].l == tr[u].r) {
tr[u].sum = tr[u].sum + (add * tr[u].len());
return;
}
tr[u].add = tr[u].add + add;
tr[u].sum = tr[u].sum + (add * tr[u].len());
}
void push_mul(int u, Complex mul) {
if (tr[u].l == tr[u].r) {
tr[u].sum = tr[u].sum * mul;
return;
}
tr[u].mul = tr[u].mul * mul;
tr[u].sum = tr[u].sum * mul;
tr[u].add = tr[u].add * mul;
}
void pushdown(int u) {
if (tr[u].l == tr[u].r) return;
if (!tr[u].mul.isI()) {
push_mul(ls, tr[u].mul);
push_mul(rs, tr[u].mul);
tr[u].mul.makeI();
}
if (!tr[u].add.empty()) {
push_add(ls, tr[u].add);
push_add(rs, tr[u].add);
tr[u].add.clear();
}
}
void build(int u, int l, int r) {
tr[u] = {l, r}, tr[u].mul.makeI();
if (l == r) {
tr[u].sum = Complex(p[r].first, p[r].second);
return;
}
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
pushup(u);
}
void Multiply(int u, int l, int r, Complex k) {
if (tr[u].l >= l && tr[u].r <= r) {
push_mul(u, k); return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) Multiply(ls, l, r, k);
if (r > mid) Multiply(rs, l, r, k);
pushup(u);
}
void Add(int u, int l, int r, Complex k) {
if (tr[u].l >= l && tr[u].r <= r) {
push_add(u, k); return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) Add(ls, l, r, k);
if (r > mid) Add(rs, l, r, k);
pushup(u);
}
Complex query(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1; Complex ans(0, 0);
if (l <= mid) ans = ans + query(ls, l, r);
if (r > mid) ans = ans + query(rs, l, r);
return ans;
}
void modify1(int l, int r, int a, int b) {
Complex A(a, b); Add(1, l, r, A);
}
void modify2(int l, int r, int a, int b, int alpha) {
Complex t(Sin[alpha], Cos[alpha]); Complex M(-a, -b);
Multiply(1, l, r, t); Add(1, l, r, M * t - M);
}
void modify3(int l, int r, int a, int b, double k) {
Complex t(0, k); Complex M(-a, -b);
Multiply(1, l, r, t), Add(1, l, r, M * t - M);
}
int main() {
read(n, m);
for (int i = 1; i <= n; i ++ )
read(p[i].first, p[i].second);
build(1, 1, n);
for (int i = 0; i < 360; i ++ )
Sin[i] = sin((double)i * pi / 180.00), Cos[i] = cos((double)i * pi / 180.00);
while (m -- ) {
int op, l, r, a, b;
int g, p, q;
read(op, l, r);
if (op == 1) read(a, b), modify1(l, r, a, b);
if (op == 2) read(a, b, g), modify2(l, r, a, b, g);
if (op == 3) read(a, b, p, q), modify3(l, r, a, b, (double)p / q);
if (op == 4) { Complex ans = query(1, l, r); printf("%.4lf %.4lf\n", (double)ans.x / (r - l + 1), (double)ans.y / (r - l + 1)); }
}
return 0;
}