poj crane

时间:2023-03-10 06:24:59
poj crane
 #include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define N (10010<<2)
#define maxn 10000
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pi acos(-1.0) int ang[N];
double x[N],y[N],len[maxn+]; void Rotate(int rt,double rad)
{
double s=x[rt],t=y[rt];
x[rt]=s*cos(rad)-t*sin(rad);
y[rt]=s*sin(rad)+t*cos(rad);
} double getrad(double x)
{
return x*pi/180.0;
} void PushDown(int rt)
{
if(ang[rt])
{
ang[rt<<]+=ang[rt];
ang[rt<<|]+=ang[rt];
double rad=getrad(ang[rt]);
ang[rt]=;
Rotate(rt<<,rad);
Rotate(rt<<|,rad);
}
} void PushUp(int rt)
{
x[rt]=x[rt<<]+x[rt<<|];
y[rt]=y[rt<<]+y[rt<<|];
} void build(int l,int r,int rt)
{
ang[rt]=;
if(l==r)
{
x[rt]=;
y[rt]=len[l];
return ;
}
int m=(l+r)>>;
build(lson);
build(rson);
PushUp(rt);
} void update(int p,int del,int l,int r,int rt)
{
if(l==r)
{
double rad=getrad(del);
Rotate(rt,rad);
return;
}
int m=(l+r)>>;
PushDown(rt);
if(p<=m)
{
double rad=getrad(del);
update(p,del,lson);
Rotate(rt<<|,rad);
ang[rt<<|]+=del;
}
else
update(p,del,rson);
PushUp(rt);
} int main(void)
{
int n,q;
int flag=;
int index,degree[maxn+],d;
while(~scanf("%d%d",&n,&q))
{
memset(degree,,sizeof(degree));
memset(ang,,sizeof(ang));/*旋转角度初始化为0,也就是一开始不旋转,这一步也可以放在build函数里面进行,不能遗漏*/
if(flag) puts("");
else flag=;
for(int i=; i<=n; i++)
scanf("%lf",len+i);
build(,n,);
while(q--)
{
scanf("%d%d",&index,&d);
d-=;
index++;/*index要先增加,然后再和degree[intdex]求旋转角度*/
int delta=d-degree[index];
degree[index]=d;
update(index,delta,,n,);
printf("%.2f %.2f\n",x[],y[]);
}
}
return ;
}

关于Rotae函数是这样理解的,更新时表示index+1段之后的线段绕index段末端点旋转delta度,x,y分别对应index+1之后的线段在x轴,y轴上投影。
根据x'=x*cos(rad)-y*sin(rad),y'=x*sin(rad)+y*cos(rad)可以将旋转后的投影算出来。