【题意】

有一个为N节的机械手,每次可以让某个关节点旋转到某一角度,问旋转操作结束之后最末端节点的坐标。

【解题方法】

当第i段与第i+1段之间的关节进行旋转时,从第i+1段到第n段都要进行旋转,类似于成段更新(成段旋转),如果把每个线段看成一个向量的话,末端的坐标等于所有向量的和。已知某个点的坐标(x,y),求逆时针旋转之后的坐标:

【AC code】
//POJ.2991
//Crane

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=10010;

struct node{
    int l,r;
    double x,y;
    int lazy;
}Tree[maxn<<2];
int angel[maxn];
//int input[maxn];
void init()
{
    for(int i=1; i<=maxn; i++) angel[i]=180.0;
}
void Rotate(int rt,int d)
{
    double x,y;
    double dd;
    dd=(double)d*acos(-1.0)/180.0;
    x=Tree[rt].x*cos(dd)-Tree[rt].y*sin(dd);
    y=Tree[rt].x*sin(dd)+Tree[rt].y*cos(dd);
    Tree[rt].x=x;
    Tree[rt].y=y;
}
void PushUp(int rt)
{
    Tree[rt].x=Tree[rt<<1].x+Tree[rt<<1|1].x;
    Tree[rt].y=Tree[rt<<1].y+Tree[rt<<1|1].y;
}
void PushDown(int rt)
{
    if(Tree[rt].lazy)
    {
        Tree[rt*2].lazy+=Tree[rt].lazy;
        Tree[rt*2+1].lazy+=Tree[rt].lazy;
        Rotate(rt*2,Tree[rt].lazy);
        Rotate(rt*2+1,Tree[rt].lazy);
        Tree[rt].lazy=0;
    }
}
void Build(int l,int r,int rt)
{
    Tree[rt].l=l,Tree[rt].r=r;
    Tree[rt].lazy=0;
    if(l==r)
    {
        Tree[rt].x=0;
        scanf("%lf",&Tree[rt].y);
        return ;
    }
    int mid=(l+r)/2;
    Build(l,mid,rt*2);
    Build(mid+1,r,rt*2+1);
    PushUp(rt);
}
void update(int L,int R,int val,int rt)
{
    if(L<=Tree[rt].l&&Tree[rt].r<=R)
    {
        Tree[rt].lazy+=val;
        Rotate(rt,val);
        return ;
    }
    PushDown(rt);
    int mid=(Tree[rt].l+Tree[rt].r)/2;
    if(L<=mid) update(L,R,val,rt*2);
    if(mid<R)  update(L,R,val,rt*2+1);
    PushUp(rt);
}
int main()
{
    int n,c;
    while(~scanf("%d%d",&n,&c))
    {
        Build(1,n,1);
        init();
        //puts("success");
        int a,b;
        for(int i=1; i<=c; i++)
        {
            scanf("%d%d",&a,&b);
            update(a+1,n,b-angel[a],1);
            angel[a]=(double)b;
            printf("%.2f %.2f\n",Tree[1].x,Tree[1].y);
        }
    }
}