POJ 2991 Crane 线段树
来源:互联网 发布:mac电脑excel表格下载 编辑:程序博客网 时间:2024/05/18 06:27
这个题比较神奇。大意就是有一个长杆,杆上有一些关节点,可以转动,然后每次操作就是将某个关节点的角度变成某个角度,最后求末尾的坐标。
线段树每个结点存的信息是,这一段末尾的x坐标,y坐标,以及该段与y轴的夹角,其中x,y坐标是与上一段线段的相对坐标。这样的好处是显而易见的。注意,这个与y轴的夹角是该段线段顺时针旋转至初始状态的角度,如下图
然后每次更新的时候需要注意,是把某个结点后的所有线段都旋转
/*ID: sdj22251PROG: inflateLANG: C++*/#include <iostream>#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <cstring>#include <cmath>#include <ctime>#define MAXN 10005#define INF 1000000000#define L(x) x<<1#define R(x) x<<1|1#define PI acos(-1.0)#define eps 1e-7using namespace std;int len[MAXN];struct node{ int left, right, mid; double x, y; int turn;}tree[4 * MAXN];void up(int C){ tree[C].y = tree[L(C)].y + tree[R(C)].y; tree[C].x = tree[L(C)].x + tree[R(C)].x;}void change(int C, int turn){ tree[C].turn = (tree[C].turn + turn) % 360; double tx = tree[C].x; double ty = tree[C].y; double degree = turn * 1.0 / 180.0 * PI; tree[C].x = tx * cos(degree) - ty * sin(degree); tree[C].y = tx * sin(degree) + ty * cos(degree);}void down(int C){ if(tree[C].turn) { change(L(C), tree[C].turn); change(R(C), tree[C].turn); tree[C].turn = 0; }}void make_tree(int s, int e, int C){ tree[C].left = s; tree[C].right = e; tree[C].mid = (s + e) >> 1; tree[C].x = 0; tree[C].turn = 0; if(s == e) {tree[C].y = len[s]; return;} make_tree(s, tree[C].mid, L(C)); make_tree(tree[C].mid + 1, e, R(C)); up(C);}int query(int C, int p){ if(tree[C].left == tree[C].right) return tree[C].turn; down(C); if(tree[C].mid >= p) return query(L(C), p); else return query(R(C), p);}void update(int s, int e, int turn, int C){ if(tree[C].left >= s && tree[C].right <= e) { change(C, turn); return; } down(C); if(tree[C].mid >= s) update(s, e, turn, L(C)); if(tree[C].mid < e) update(s, e, turn, R(C)); up(C);}int main(){ int n, c; int x, y; bool fg = 0; while(scanf("%d%d", &n, &c) != EOF) { if(fg) puts(""); fg = 1; for(int i = 1; i <= n; i++) scanf("%d", &len[i]); make_tree(1, n, 1); for(int i = 1; i <= c; i++) { scanf("%d%d", &x, &y); int pos1 = query(1, x); int pos2 = query(1, x + 1); int t = (-180 + pos1 - pos2 + y + 360) % 360; update(x + 1, n, t, 1); printf("%.2f %.2f\n", tree[1].x + eps, tree[1].y + eps); } } return 0;}
- POJ 2991 Crane 线段树
- 线段树 POJ 2991Crane
- poj 2991 Crane(线段树)
- POJ 2991 Crane (线段树)
- POJ 2991 Crane 线段树
- 【POJ 2991 Crane】+ 线段树
- poj 2991--Crane(线段树)
- poj 2991 Crane 线段树lazy_tag
- poj 2991 Crane 线段树 几何
- Crane(POJ-2991)(线段树)
- poj Crane 线段树变种
- POJ 2991 Crane(线段树:维护向量+计算几何)
- POJ - 2991 Crane (线段树+计算几何)
- POJ 2991 Crane(线段树+计算几何)
- POJ 2991 Crane(线段树+计算几何)
- POJ 2991 Crane(线段树·向量旋转)
- POJ 2991 Crane (线段树 维护旋转的向量和)
- POJ 题目2991 Crane(线段树+计算几何)
- Android开发经验之点击图片判断是否在图片范围之内
- linux 安装tomcat7
- 文件输入流 文件要放在 project目录下
- android完全退出应用程序
- 给每个IIS站点建立一个用户的方法与好处
- POJ 2991 Crane 线段树
- 2012-03-01
- Fixjob作业计划——介绍
- 如何使用PathFileExists
- Sicily 4834. Party Location
- Ubuntu 小企鹅输入法fcitx安装及设置
- shell make的区别
- 金山(Kingsoft)笔试面试题整理之002
- http://acm.hdu.edu.cn/showproblem.php?pid=2688&&树状数组求正序数