向量 (x,y) 逆时针旋转 θ :
x′=x∗cosθ−y∗sinθ
y′=x∗sinθ+y∗cosθ
相对旋转量
语言的坑:
printf("%.2lf %.2lf", vx[0], vy[0])
导致超时的悲剧
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
const double M_PI = acos(-1);
const int MAX_N = 10001;
const int ST_SIZE = (1 << 15) - 1;
int N, C;
int L[MAX_N];
double vx[ST_SIZE], vy[ST_SIZE];
double ang[ST_SIZE];
double prev[MAX_N];
// 初始化线段树,结点编号k,表示区间[l,r)
void init(int k, int l, int r) {
ang[k] = vx[k] = 0;
if (l == r - 1) {
vy[k] = L[l];
} else {
int lc = 2 * k + 1, rc = 2 * k + 2;
int m = (l + r) / 2;
init(lc, l, m);
init(rc, m, r);
vy[k] = vy[lc] + vy[rc];
}
}
//线段树更新,第s和s+1段角度加a,k结点编号,表示区间[l,r)
void change(int s, double a, int k, int l, int r) {
if (s < l || r <= s + 1) return;
int lc = 2 * k + 1, rc = 2 * k + 2;
int m = (l + r) / 2;
change(s, a, lc, l, m);
change(s, a, rc, m, r);
if (s < m) ang[k] += a;
double si = sin(ang[k]), co = cos(ang[k]);
vx[k] = vx[lc] + (vx[rc] * co - vy[rc] * si);
vy[k] = vy[lc] + (vx[rc] * si + vy[rc] * co);
}
int main() {
while (scanf("%d %d", &N, &C) != EOF) {
for (int i = 1; i <= N; i++) scanf("%d", L + i);
init(0, 1, N + 1);
for (int i = 1; i < N; i++) prev[i] = M_PI;
for (int i = 0; i < C; i++) {
int s, a; scanf("%d %d", &s, &a);
double b = a * 1.0 / 360 * 2 * M_PI;
change(s, b - prev[s], 0, 1, N + 1);
prev[s] = b;
printf("%.2f %.2f\n", vx[0], vy[0]);
}
printf("\n");
}
return 0;
}