Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5772   Accepted: 1571   Special Judge

Description

ACM has bought a new crane (crane -- jeřáb) . The crane consists of n segments of various lengths, connected by flexible joints. The end of the i-th segment is joined to the beginning of the i + 1-th one, for 1 ≤ i < n. The beginning of the first segment is
fixed at point with coordinates (0, 0) and its end at point with coordinates (0, w), where w is the length of the first segment. All of the segments lie always in one plane, and the joints allow arbitrary rotation in that plane. After series of unpleasant
accidents, it was decided that software that controls the crane must contain a piece of code that constantly checks the position of the end of crane, and stops the crane if a collision should happen. 



Your task is to write a part of this software that determines the position of the end of the n-th segment after each command. The state of the crane is determined by the angles between consecutive segments. Initially, all of the angles are straight, i.e., 180o.
The operator issues commands that change the angle in exactly one joint. 

Input

The input consists of several instances, separated by single empty lines. 



The first line of each instance consists of two integers 1 ≤ n ≤10 000 and c 0 separated by a single space -- the number of segments of the crane and the number of commands. The second line consists of n integers l1,..., ln (1 li 100) separated by single spaces.
The length of the i-th segment of the crane is li. The following c lines specify the commands of the operator. Each line describing the command consists of two integers s and a (1 ≤ s < n, 0 ≤ a ≤ 359) separated by a single space -- the order to change the
angle between the s-th and the s + 1-th segment to a degrees (the angle is measured counterclockwise from the s-th to the s + 1-th segment).

Output

The output for each instance consists of c lines. The i-th of the lines consists of two rational numbers x and y separated by a single space -- the coordinates of the end of the n-th segment after the i-th command, rounded to two digits after the decimal point. 



The outputs for each two consecutive instances must be separated by a single empty line.

Sample Input

2 1
10 5
1 90 3 2
5 5 5
1 270
2 90

Sample Output

5.00 10.00

-10.00 5.00
-5.00 10.00

Source

【题解】

题意就是说把n条线段从下往上竖直堆积。然后有时候会给你几个操作。要求把第s个的上面那个棍子(s+1)转到一定的角度。(以第s个棍子作为衡量角度的参照物);

这题我们不要管它转到多少度。而只需要知道它转的这个角度和前一个角度的差是多少就可以了。

每次遇到一个角度就减去180度。

然后用减去180度的角和之前它的角相减。就能得到角度差了。为什么减去180度等下会讲到。

然后我们把这n条线段看成一个个向量。那么从头加到尾。就能够得到最上面那条线段的顶点坐标了。(向量加法);

这样看来。我们只要维护这n条线段的向量和就可以了。

然后其中一个向量m它的角度转了x度,则m+1,m+2..n它们的向量也都会转x度。

而一个向量砖了x度之后。我们是能够求出它新的向量坐标形式的。

x' = cosa*x-sina*y;

y' = sina*x+cosa*y;

(a是旋转的角度);

推导过程看下面.

推导的基础就是一条线段它转了之后,长度是不会变的!

然后注意这是逆时针转的情况。

所以我们一开始减去180度。

比如样例90,减去180就变成-90了

然后套用这个公式就变成逆时针旋转(-90)也就是顺时针转90度了。

而这正是我们所需的。(可以带进样例试试。)

注意减去180度之后,要重新记录k+1的角度,方便下次对k+1操作。(输入的是k,但是我们实际在对k+1进行操作!);

然后我们在做线段树的时候对k+1,k+2...n进行相同的旋转操作即可。

然后维护一下区间的向量和。

//然后一开始的区间向量和的x坐标都是0,y坐标的和就用前缀和的方法获得。

具体的过程看代码;

ps:突然发现如果define里面比如define MAXN 10000+10 ,交上去后会runtime error。。。就是define里面貌似不能写表达式。。以后都用const吧。const 即不会有事。。

acos(-1.0)==pi

里面的点号不能漏,不然它会以为你输入的是整形然后会Compile error

【代码】

#include <cstdio>
#include <cmath>
#define lson begin,m,rt<<1
#define rson m+1,end,rt<<1|1 const int MAXN = 10000 + 100;
const double pi = acos(-1.0); int n, c;
int a[MAXN];
double sum[MAXN * 4][2];
int lazy_tag[MAXN * 4];
int pre[MAXN]; void build(int begin, int end, int rt)//建树
{
lazy_tag[rt] = 0;
sum[rt][1] = a[end] - a[begin - 1];//一开始建树的时候就能处理区间和了
sum[rt][0] = 0;
if (begin == end)
return;
int m = (begin + end) >> 1;
build(lson);
build(rson);
} void input_data()
{
a[0] = 0;
for (int i = 1; i <= n; i++)
{
int len;
scanf("%d", &len);
a[i] = a[i - 1] + len;//获取前缀和,用来处理一开始的初始区间和
pre[i] = 0;//这是第i个棍子的初始角度置0就可以。
}
build(1, n, 1);
} double get_rad(int k) //获取角度k的弧度制。
{
double temp = (k * pi)/180;
return temp;
} void rotation(int rt, double rad) //根据坐标和选择角度更改这个向量
{
//y = sina*x+cosa*y
//x = cosa*x-sina*y
double dx = sum[rt][0], dy = sum[rt][1];
sum[rt][0] = cos(rad)*dx - sin(rad)*dy;
sum[rt][1] = sin(rad)*dx + cos(rad)*dy;
} void push_up(int rt)
{
sum[rt][0] = sum[rt << 1][0] + sum[rt << 1 | 1][0];
sum[rt][1] = sum[rt << 1][1] + sum[rt << 1 | 1][1];
} void push_down(int rt)//传递懒惰标记
{
if (lazy_tag[rt] != 0)
{
double temp = get_rad(lazy_tag[rt]);
rotation(rt << 1, temp);
rotation(rt << 1 | 1, temp); //把儿子们旋转
lazy_tag[rt << 1] += lazy_tag[rt];
lazy_tag[rt << 1 | 1] += lazy_tag[rt];
lazy_tag[rt] = 0;
}
} void updata(int k, int change, int begin, int end, int rt)
{
if (begin == end)
{
double hudu = get_rad(change);
rotation(begin,hudu);//只有一个点 那就是要旋转的了。
return;
}
push_down(rt);
int m = (begin + end) >> 1;
if (k <= m + 1) //这个意思是说右儿子全是大于等于k的节点。那么就要全部旋转
{
double hudu = get_rad(change);
if (k <= m)//左区间可能还有部分需要旋转
updata(k, change, lson);
rotation(rt << 1 | 1, hudu);//因为要全部旋转所以就用懒惰标记。
lazy_tag[rt << 1 | 1] += change;
}
else
if (k > m + 1)//k>m+1的话左边就全是小于k的节点了(不用管)。只要处理右边就好
updata(k, change, rson);
push_up(rt);
} void get_ans()
{
for (int i = 1; i <= c; i++)
{
int number, degree;
scanf("%d%d", &number, °ree);
number++;//要处理的是number+1
int d = degree - 180;
int change = d - pre[number];
pre[number] = d;
updata(number, change,1, n, 1);
printf("%.2lf %.2lf\n", sum[1][0], sum[1][1]);
}
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
//freopen("F:\\rush_out.txt", "w", stdout);
bool flag = false;
while (scanf("%d%d", &n, &c) == 2)
{
if (flag)
printf("\n");
input_data();
get_ans();
flag = true;
}
return 0;
}

【27.22%】【poj2991】Crane的更多相关文章

  1. JAVA 基础编程练习题22 【程序 22 递归求阶乘】

    22 [程序 22 递归求阶乘] 题目:利用递归方法求 5!. 程序分析:递归公式:fn=fn_1*4! package cskaoyan; public class cskaoyan22 { @or ...

  2. 27. Remove Element【leetcode】

    27. Remove Element[leetcode] Given an array and a value, remove all instances of that value in place ...

  3. 1333:【例2-2】Blah数集

    1333:[例2-2]Blah数集 注意是数组,答案数组中不能有重复数字 q数组是存储答案的 代码: #include<iostream> #include<cstdio> # ...

  4. 27. Remove Element【easy】

    27. Remove Element[easy] Given an array and a value, remove all instances of that value in place and ...

  5. 【UOJ#22】【UR #1】外星人(动态规划)

    [UOJ#22][UR #1]外星人(动态规划) 题面 UOJ 题解 一道简单题? 不难发现只有按照从大往小排序的顺序选择的才有意义,否则先选择一个小数再去模一个大数是没有意义的. 设\(f[i][j ...

  6. Selenium3自动化测试【27】Frame的操作

    本篇文章内容摘要 " 讲解Python3+Selenium3如何处理Frame窗体" 同步视频知识与系列知识内容,可关注:[公众号]:柒哥测试:[WX]:Lee-890;[视频号] ...

  7. 【ASP.NET程序员福利】打造一款人见人爱的ORM(二)

    上一篇我已经给大家介绍AntORM的框架[ASP.NET程序员福利]打造一款人见人爱的ORM(一),今天就来着重介绍一下如何使用这套框架 1>AntORM 所有成员 如果你只想操作一种数据库,可 ...

  8. 【刷题记录】 && 【算法杂谈】折半枚举与upper_bound 和 lower_bound

    [什么是upper_bound 和 lower_bound] 简单来说lower_bound就是你给他一个非递减数列[first,last)和x,它给你返回非递减序列[first, last)中的第一 ...

  9. 【iScroll源码学习04】分离IScroll核心

    前言 最近几天我们前前后后基本将iScroll源码学的七七八八了,文章中未涉及的各位就要自己去看了 1. [iScroll源码学习03]iScroll事件机制与滚动条的实现 2. [iScroll源码 ...

随机推荐

  1. 设计模式六大原则(三):依赖倒置原则(Dependence Inversion Principle)

    依赖倒置原则(DIP)定义: 高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 问题由来: 类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码 ...

  2. [bzoj1269]文本编辑器editor [bzoj1500]维修数列

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2540 Solved: 923 [Submit ...

  3. iOS 之应用性能调优的25个建议和技巧

    注意:每在优化代码之前,你都要注意一个问题,不要养成"预优化"代码的错误习惯. 时常使用Instruments去profile你的代码来发现须要提升的方面.Matt Gallowa ...

  4. 页面事件(Init,Load,PreRender)执行顺序

    简介 对由 Microsoft® Internet 信息服务 (IIS) 处理的 Microsoft® ASP.NET 页面的每个请求都会被移交到 ASP.NET HTTP 管道.HTTP 管道由一系 ...

  5. 微信支付v2开发(1) 微信支付URL配置

    本文介绍微信支付申请时如何设置授权目录及URL. 在申请微信支付时,第一项就会碰到下图的配置. 下面就对这一设置进行讲解! 一.选择支付类型 目前有两种支付类型 JS API网页支付 Native原生 ...

  6. JS错误记录 - fgm练习 - 函数传参

    <script> window.onload = function() { var oBtn = document.getElementsByTagName('button')[0]; v ...

  7. JS学习笔记 - fgm练习 - 鼠标移入/移出div样式改变

    思路: div的默认样式正常设置. 鼠标移入时,发生改变的样式有3个,即 边框颜色,div背景色,字体颜色. 把这三个css改变设置在一个类名下,再通过js给div动态 添加/去除这个类名,实现div ...

  8. OFFICE2013 打开两个word文档卡死的解决办法

    这几天Office打开一个word好好的,两个就直接卡死了,百度了一下: 原文地址: http://hi.baidu.com/pjhero/item/ca326e3dcfebebb9623aff6e ...

  9. 微服务实战(一):微服务架构的优势与不足 - DockOne.io

    原文:微服务实战(一):微服务架构的优势与不足 - DockOne.io [编者的话]本文来自Nginx官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战 ...

  10. Spring Boot使用模板freemarker【从零开始学Spring Boot(转)

    视频&交流平台: à SpringBoot网易云课堂视频 http://study.163.com/course/introduction.htm?courseId=1004329008 à  ...