题目地址 题意:你有一个挖掘机,他的臂由n根小臂组成,最初的时候挖掘机的臂是垂直向上的,然后有n次操作,每次操作告诉你把第a和第a+1根臂之间的角度旋转为b(不是旋转角度为b),每次操作之后把最后那个臂的坐标输出 思路:用线段树去维护每个臂的向量,然后把第a和第a+1个臂之间的角度旋转为b这个操作就是将a+1到n个臂旋转b-rad[a]就好了,最后输出sum[1].x和sum[1].y就是最后那个臂的向量坐标 吐槽一下:为什么POJ要卡G++的时间,搞得TLE,还有自己太久没有用c了居然有个地方忘了加&,RE了一个下午(浪费了一个下午)
#include <iostream> #include <cstring> #include <string> #include <queue> #include <vector> #include <map> #include <set> #include <stack> #include <cmath> #include <cstdio> #include <algorithm> #include <iomanip> #define N 10005 #define LL __int64 #define inf 0x3f3f3f3f #define lson l,mid,ans<<1 #define rson mid+1,r,ans<<1|1 #define getMid (l+r)>>1 #define movel ans<<1 #define mover ans<<1|1 using namespace std; const LL mod = 1e9 + 7; const double eps = 1e-8; const double pi = acos(-1.0); struct node { double x, y; double lazy; }sum[N << 2];//线段树主体 double rad[N]; void rotate(double &x, double &y, double r){ //将向量(x, y)逆时针旋转r弧度 double xx = x; x = xx * cos(r) - y * sin(r); y = xx * sin(r) + y * cos(r); } struct Segment__Tree { int x, y; void pushUp(int ans) { sum[ans].x = sum[movel].x + sum[mover].x; sum[ans].y = sum[movel].y + sum[mover].y; } void pushDown(int ans) { if (fabs(sum[ans].lazy)>=eps) { sum[movel].lazy += sum[ans].lazy;//可能还有原来没有pushDown的标记 sum[mover].lazy += sum[ans].lazy; rotate(sum[movel].x, sum[movel].y, sum[ans].lazy); rotate(sum[mover].x, sum[mover].y, sum[ans].lazy); sum[ans].lazy = 0; } } void build(int l, int r, int ans) { sum[ans].lazy = 0; if (l == r) { sum[ans].x = 0; rad[l] = pi; scanf("%lf", &sum[ans].y);//居然忘了加&,RE了一个下午 return; } int mid = getMid; build(lson); build(rson); pushUp(ans); } void updata(int l, int r, int ans, double nums) { if (l >= x&&r <= y) { sum[ans].lazy += nums; rotate(sum[ans].x, sum[ans].y, nums); return; } pushDown(ans); int mid = getMid; if (mid<x) { updata(rson, nums); } else if (mid >= y) { updata(lson, nums); } else { updata(lson, nums); updata(rson, nums); } pushUp(ans); } }; int main() { //cin.sync_with_stdio(false); Segment__Tree tree; int n, m; int a; double b; bool flag = false; while (~scanf("%d %d", &n, &m)) { tree.y = n; if (flag) { printf("\n"); } else flag = true; tree.build(1, n, 1); while (m--) { scanf("%d %lf", &a, &b); //cin >> a >> b; b = b / 180 * pi;//转化为弧度 tree.x = a + 1; tree.updata(1, n, 1, b - rad[a]); rad[a] = b; printf("%.2lf %.2lf\n", sum[1].x, sum[1].y); //cout << setiosflags(ios::fixed) << setprecision(2) << sum[1].x << " " << sum[1].y << endl; } } return 0; }