标签:acm
题意 有一个Crane由n条线段连接组成 每个连接点处均可以任意旋转 给你n条线段的长度 然后又m次旋转操作 给你p和r 将第p和第p+1条线段之间的角度旋转为r 即第p条线段绕p的终点逆时针旋转r度后能够与第p+1条重合 问每次旋转后最后一条线段的终点坐标
可以发现 旋转第p+1条线段时 p+1后面的所有线段也一起旋转了 可以把Crane分解为n个向量 这些向量的和也就是Crane终点的坐标 用rad[i]保存第i个向量与第i+1个向量之间的夹角 每次旋转操作时 我们要把rad[i]变为r 也就是要把第i+1和后面的所有向量逆时针旋转r - rad[i] 对于向量的旋转操作有
(x,y) 逆时针旋转 r 弧度 --> (x*cos(r) - y*sin(r), x*sin(r) + y*cos(r))
(x,y)
顺时针旋转 r 弧度 --> (-x*cos(r) + y*sin(r), x*sin(r) + y*cos(r))
那么我们可以用线段树来维护对应区间的向量的和 根节点对应的x, y也就是答案了
#include <cstdio>
#include <cmath>
#define lc p<<1, s, mid
#define rc p<<1|1, mid+1, e
#define mid ((s+e)>>1)
using namespace std;
const int N = 10005;
const double pi = acos(-1.0);
const double eps = 1e-8;
double x[N << 2], y[N << 2], rot[N << 2];
//x 对应区间所有向量的和的横坐标
//y 对应区间所有向量的和的纵坐标
//rot 子节点对应区间所有向量需要逆时针旋转的弧度
double rad[N]; //rad[i] 保存第i个向量和第i+1个向量间的弧度
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);
}
void pushup(int p)
{
x[p] = x[p << 1] + x[p << 1 | 1];
y[p] = y[p << 1] + y[p << 1 | 1];
}
void pushdown(int p, int s, int e)
{
if(fabs(rot[p]) < eps) return;
int lp = p << 1, rp = p << 1 | 1;
rot[lp] += rot[p];
rot[rp] += rot[p];
rotate(x[lp], y[lp], rot[p]);
rotate(x[rp], y[rp], rot[p]);
rot[p] = 0;
}
void build(int p, int s, int e)
{
rot[p] = 0;
if(s == e)
{
scanf("%lf", &y[p]);
x[p] = 0;
rad[s] = pi;
return;
}
build(lc);
build(rc);
pushup(p);
}
void update(int p, int s, int e, int l, int r, double v)
{
if(l <= s && e <= r)
{
rot[p] += v;
rotate(x[p], y[p], v);
return;
}
pushdown(p, s, e);
if(l <= mid) update(lc, l, r, v);
if(r > mid) update(rc, l, r, v);
pushup(p);
}
int main()
{
int n, m, p, first = 1;
double r;
while(~scanf("%d%d", &n, &m))
{
if(!first) puts("");
else first = 0;
build(1, 1, n);
while(m--)
{
scanf("%d%lf", &p, &r);
r = r / 180 * pi;
//p与p+1之间的弧度为rad[p] 要达到r p+1还需要逆时针旋转r - rad[p]弧度
update(1, 1, n, p + 1, n, r - rad[p]);
rad[p] = r; //旋转后p与p+1之间的弧度变为r
printf("%f %f\n", x[1], y[1]); //x[1], y[1]为所有向量和的坐标
}
}
return 0;
}
Description
Input
Output
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
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:acm
原文地址:http://blog.csdn.net/acvay/article/details/47702385