poj 2991 线段树 成段更新 + 向量旋转

原创 2016年12月04日 22:21:20

题目链接:http://poj.org/problem?id=2991

输入数据:

n条线段,c条指令

n条线段的长度li(最初的线段都是在y轴上的)

c条的指令是s,a,表示第s条线段和第s+1条线段的夹角调整为a度

每执行完一条命令输出最后一条线段末尾的坐标


注意:输出的时候,c++中用%lf,g++中用%f。

keep[maxn]保存第i条边与i-1边的夹角(初始化为180°)

每次线段要旋转的角度由a-keep[s]得到(记得更新keep[s]=a)

向量公式

         t= a-keep[s];//t的正负不影响结果

         x1=x0*cos(t*PI/180) - y0*sin(t*PI/180);

 y1=y0*cos(t*PI/180) + x0*sin(t*PI/180);      

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std;
 
const int maxn = 10010;
const double PI = acos(-1.0);//求出π的值
 
struct node
{
         intl;
         intr;
         doublex;
         doubley;
         intangle;
}tree[maxn*4];
int n,c;
int len[maxn];
int keep[maxn];
 
void turn(int p,int t)
{
         doublex0 = tree[p].x;
         doubley0 = tree[p].y;
         tree[p].x= x0*cos(t*PI/180) - y0*sin(t*PI/180);// sin,cos函数里面用的都是弧度,转换
         tree[p].y= y0*cos(t*PI/180) + x0*sin(t*PI/180);             
}
 
void create(int p,int l,int r)
{
         tree[p].l= l;
         tree[p].r= r;
         if(l== r)
         {
                   tree[p].x= 0;
                   tree[p].y= len[l];
                   return;
         }
         intmid = (l+r)>>1;
         create(p<<1,l,mid);
         create(p<<1|1,mid+1,r);
         tree[p].x= 0;
         tree[p].y= tree[p<<1].y + tree[p<<1|1].y;
         tree[p].angle= 0;
}
void pushdown(int p)
{
         if(tree[p].angle!= 0)
         {
                   turn(p<<1,tree[p].angle);
                   turn(p<<1|1,tree[p].angle);
                   tree[p<<1].angle+= tree[p].angle;
                   tree[p<<1|1].angle+= tree[p].angle;
                   tree[p].angle= 0;
         }
}
 
void update(int p, int l, int r, int TurnA)
{
         if(tree[p].l== l && tree[p].r == r)
         {
                   tree[p].angle+= TurnA;
                   turn(p,TurnA);
                   return;
         }
         pushdown(p);
         intmid = (tree[p].l+tree[p].r)>>1;
         if(r<= mid)
                   update(p<<1,l,r,TurnA);
         elseif(l > mid)
                   update(p<<1|1,l,r,TurnA);
                   else
                   {
                            update(p<<1,l,mid,TurnA);
                            update(p<<1|1,mid+1,r,TurnA);
                   }
         tree[p].x= tree[p<<1].x + tree[p<<1|1].x;
         tree[p].y= tree[p<<1].y + tree[p<<1|1].y;
}
 
int main()
{
         ints,a;
         intflag=0;
         while(~scanf("%d%d",&n,&c))
         {
                   if(flag)
                            printf("\n");
                   flag= 1;
                   for(inti = 1; i <= n; i++)
                   {
                            scanf("%d",&len[i]);//第i条边的长度
                            keep[i]= 180;//第i条边与前一条边的夹角
                   }
                   create(1,1,n);
 
                   for(inti = 0; i < c; i++)
                   {
                            scanf("%d%d",&s, &a);
                            s++;
                            update(1,s,n,a-keep[s]);
                            keep[s]= a;
                            printf("%.2lf%.2lf\n", tree[1].x, tree[1].y);
                   }                
         }
         return0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ2991 Crane(线段树成段更新+向量旋转)

DescriptionACM has bought a new crane (crane -- jeřáb) . The crane consists of n segments of various...
  • Viscu
  • Viscu
  • 2016年10月15日 21:21
  • 144

poj2991 Crane 向量旋转+线段树

Crane Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3962   Accepted...
  • corncsd
  • corncsd
  • 2015年03月08日 20:02
  • 229

POJ 2991 Crane(线段树·向量旋转)

题意  有一个Crane由n条线段连接组成  每个连接点处均可以任意旋转  给你n条线段的长度  然后又m次旋转操作  给你p和r  将第p和第p+1条线段之间的角度旋转为r  即第p条线段绕p的终点...
  • acvay
  • acvay
  • 2015年08月16日 15:16
  • 668

POJ 2991 Crane (线段树 维护旋转的向量和)

题目大意: 就是多个木棍初始摆在y轴上相邻的木棍间有连接着他们的东西, 相当于关节 然后每次操作旋转某个关节, 求旋转后的端点的坐标 大致思路: 首先将所有的木棍拆成多个向量, 那么考...

POJ2991_Crane_计算几何::向量化|向量旋转公式||线段树维护向量和

Crane Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6704   Accepted...
  • yuege38
  • yuege38
  • 2017年05月26日 01:00
  • 216

POJ 2991 Crane(线段树+计算几何—更新向量)

Crane Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4895   Accepted...

poj 2991【线段树-lazy+向量】

Crane Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1300   Accepted...
  • lyt9469
  • lyt9469
  • 2011年09月25日 21:18
  • 331

POJ 2991 Crane(线段树:维护向量+计算几何)

POJ 2991 Crane(向量旋转+线段树_成段更新) 分析:        首先一个向量(x,y)逆时针绕起点旋转rad度后得到的向量为: newx = x*cos(rad)-y*sin(rad...

POJ 2991-Crane(线段树-角度旋转)

Crane Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5333   Accepted: 1441   Spe...
  • MIKASA3
  • MIKASA3
  • 2016年06月17日 20:37
  • 394

[poj 2991]Crane[线段树表示向量之和,而非数量]

由于旋转会影响到该点之后所有线段的角度, 因此容易想到用线段树记录角度, 成段更新. (但是不是每一次操作都要询问一次么? 那么懒惰标记还有用么? 如果使用懒惰标记, 将一些线段视为整体, 那么这些线...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 2991 线段树 成段更新 + 向量旋转
举报原因:
原因补充:

(最多只允许输入30个字)