题目大意:

给定n条首尾相接的线段的长度

第一条从0,0开始,所有线段垂直与x轴向上延伸

给定c次操作 每次操作给定 s,a

使得 由第s条线段的角度 逆时针旋转a后 达到第s+1条线段的角度

每次操作后输出最后一条线段末尾端点的坐标

向量逆时针旋转公式为

x' = x * cos(A) - y * sin(A); y' = x * sin(A) + y * cos(A);

一个向量  (x,y)  可分解两个向量为 垂直于y轴的(x,0) 和垂直于x轴的 (0,y)

两个分向量逆时针A度后

(x',0) = ( x*coa(A),x*sin(A) )   (0,y') = ( -y*sin(A),y*cos(A) )

两个旋转后的分向量 再合并就可得到旋转后的 (x',y')

用线段树维护一段区间内由 该区间内第一段线段的起点 指向 最后一段线段的末尾的向量

每次操作更新区间时 我们只对 操作位置处于当前区间的左子区间 的区间更新

那么这样当更新一段区间时 当前向量=左子区间的向量+右子区间旋转后的的向量

并且对于区间长度为1的区间不做处理

#include <bits/stdc++.h>
using namespace std;
const double PI=acos(-1.0);
const int N=; int n,c,L[N];
double pre[N]; double angT[N<<];
double x[N<<],y[N<<]; void build(int k,int l,int r) {
angT[k]=x[k]=0.0;
if(r==l) y[k]=L[l];
else {
int lson=k*, rson=k*+;
int m=(l+r)/;
build(lson,l,m);
build(rson,m+,r);
y[k]=y[lson]+y[rson];
}
}
void change(int s,double ang,int k,int l,int r) {
if(s<l || l==r) return; // 操作位置不在范围内 或 区间长度为1 不作处理
else if(s<=r) {
int lson=k*, rson=k*+;
int m=(l+r)/;
change(s,ang,lson,l,m);
change(s,ang,rson,m+,r); // 先处理左右子区间
if(s<=m) angT[k]+=ang; // 操作位置位于区间的左子区间内 可根据左右子区间的向量更新 double sina=sin(angT[k]), cosa=cos(angT[k]);
x[k]=x[lson]+(x[rson]*cosa-y[rson]*sina);
y[k]=y[lson]+(x[rson]*sina+y[rson]*cosa);
}
} int main()
{
while(~scanf("%d%d",&n,&c)) {
for(int i=;i<=n;i++) {
scanf("%d",&L[i]);
pre[i]=PI;
}
build(,,n);
while(c--) {
int s,a; scanf("%d%d",&s,&a);
double ang=(double)a/180.0*PI;
change(s,ang-pre[s],,,n);
pre[s]=ang; // 要求改变为a度 考虑之前已改变过
printf("%.2f %.2f\n",x[],y[]);
}
printf("\n");
} return ;
}

Crane /// 向量旋转+线段树的更多相关文章

  1. 【BZOJ4311】向量(线段树分治,斜率优化)

    [BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...

  2. BZOJ 3533: [Sdoi2014]向量集( 线段树 + 三分 )

    答案一定是在凸壳上的(y>0上凸壳, y<0下凸壳). 线段树维护, 至多N次询问, 每次询问影响O(logN)数量级的线段树结点, 每个结点O(logN)暴力建凸壳, 然后O(logN) ...

  3. 2019.02.26 bzoj4311: 向量(线段树分治+凸包)

    传送门 题意: 支持插入一个向量,删去某一个现有的向量,查询现有的所有向量与给出的一个向量的点积的最大值. 思路: 考虑线段树分治. 先对于每个向量处理出其有效时间放到线段树上面,然后考虑查询:对于两 ...

  4. BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)

    Description 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); " Q x y l r (| ...

  5. 【bzoj3533】[Sdoi2014]向量集 线段树+STL-vector维护凸包

    题目描述 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);"Q x y l r (|x|,|y| < ...

  6. [SDOI2014][BZOJ3533] 向量集 [线段树+凸包]

    题面 BZOJ传送门 思路 首先当然是推式子 对于一个询问点$(x_0,y_0$和给定向量$(x_1,y_1)$来说,点积这么表达: $A=x_0x_1+y_0y_1$ 首先肯定是考虑大小关系:$x_ ...

  7. bzoj 3533: [Sdoi2014]向量集 线段树维护凸包

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3533 题解: 首先我们把这些向量都平移到原点.这样我们就发现: 对于每次询问所得到的an ...

  8. bzoj 3533 [Sdoi2014]向量集 线段树+凸包+三分(+动态开数组) 好题

    题目大意 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); "Q x y l r (|x|,|y| & ...

  9. BZOJ_4311_向量_线段树按时间分治

    BZOJ_4311_向量_CDQ分治+线段树按时间分治 Description 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 3.查询当前集合与(x,y) ...

随机推荐

  1. UVA 10242 Fourth Point

    题意:给你平行四边形两条边的顶点,让你求第四个点. 思路:要找到俩边的公共点,然后向量运算. AC代码: #include<cstdio> #include<cmath> #i ...

  2. HTML —— 表格

    复习下关于html中的表格. 基本结构: 表格由 table 标签为父标签进行包裹,可以在 table 上添加几种属性. border : 定义表格的边框. cellspacing : 间距,指单元格 ...

  3. java中trim()方法是用来干什么的?

    trim()的作用是去掉字符串两端的多余的空格,注意,是两端的空格,且无论两端的空格有多少个都会去掉,当然 中间的那些空格不会被去掉,如: String s = "  a s f g     ...

  4. php ZipArchive 压缩整个文件夹

    // Get real path for our folder $rootPath = realpath('folder-to-zip'); // Initialize archive object ...

  5. leetcode.数组.16最接近的三数之和-java

    1. 具体题目 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案 ...

  6. 关于VS的第一次使用

    参考链接:https://blog.csdn.net/qq_36556893/article/details/88605617

  7. laravel passport client_credentials

    我是使用 Laravel 5.4 + Dingo Api + passport/jwt 两个验证方式 目前需要用到 passport 的 client_credentials 获取 token成功之后 ...

  8. shell脚本明文密码隐藏且加密

    将密码放到文件中去,比如/root/.pass.txtpassword=`</root/.pass.txt`还怕密码泄露的话,就把pass.txt权限设置下. chattr +i /root/. ...

  9. Python自学:第四章 切片

    # -*- coding: GBK -*- players = ['charles', 'martina', 'michael', 'florence', 'eli'] print(players[0 ...

  10. photoshop钢笔工具简单记录

    1. 移动锚点 Ctrl + 左键 2. 增加.删除锚点 左键(显示+.-) 3. 直线曲线相互转换 Alt + 左键(注意提示) 默认情况下为直线,按住Alt鼠标左键点击目标锚点,目标锚点两边的直线 ...