zoukankan      html  css  js  c++  java
  • POJ-2991 Crane(区间更新+向量旋转)

    题目大意:n个向量首尾相连,每次操作使某个区间中的所有向量都旋转同样的角度。每次操作后都回答最后一个向量的坐标。

    题目分析:区间维护向量信息。向量旋转:x1=x0*cos(t)-y0*sin(t),y1=x0*sin(t)+y0*cos(t),其中t为旋转的角度。

    代码如下:

    # include<iostream>
    # include<cmath>
    # include<algorithm>
    # include<cstdio>
    using namespace std;
    # define mid (l+(r-l)/2)
    
    const int N=10005;
    const double PI=acos(-1.0);
    
    double x[N<<2],y[N<<2];
    int lazy[N<<2];
    int angle[N];
    
    inline void read(int &x)
    {
    	x=0;
    	char c;
    	while((c=getchar())&&(c<'0'||c>'9'));
    	x=c-'0';
    	while(c=getchar()){
    		if(c<'0'||c>'9') break;
    		x=x*10+c-'0';
    	}
    }
    
    inline double f(int x)
    {
    	return x*PI/180.0;
    }
    
    inline void pushUp(int rt)
    {
    	x[rt]=x[rt<<1]+x[rt<<1|1];
    	y[rt]=y[rt<<1]+y[rt<<1|1];
    }
    
    inline void pushDown(int rt)
    {
    	if(lazy[rt]==0) return ;
    	lazy[rt<<1]+=lazy[rt];
    	lazy[rt<<1|1]+=lazy[rt];
    	
    	double xx=x[rt<<1];
    	double yy=y[rt<<1];
    	x[rt<<1]=xx*cos(f(lazy[rt]))-yy*sin(f(lazy[rt]));
    	y[rt<<1]=xx*sin(f(lazy[rt]))+yy*cos(f(lazy[rt]));
    	
    	xx=x[rt<<1|1];
    	yy=y[rt<<1|1];
    	x[rt<<1|1]=xx*cos(f(lazy[rt]))-yy*sin(f(lazy[rt]));
    	y[rt<<1|1]=xx*sin(f(lazy[rt]))+yy*cos(f(lazy[rt]));
    	lazy[rt]=0;
    }
    
    inline void build(int rt,int l,int r)
    {
    	lazy[rt]=0;
    	if(l==r){
    		x[rt]=0.0;
    		int a;
    		read(a);
    		y[rt]=a;
    	}else{
    		build(rt<<1,l,mid);
    		build(rt<<1|1,mid+1,r);
    		pushUp(rt);
    	}
    }
    
    inline void update(int rt,int l,int r,int L,int R,int a)
    {
    	if(L<=l&&r<=R){
    		lazy[rt]+=a;
    		double xx=x[rt];
    		double yy=y[rt];
    		x[rt]=xx*cos(f(a))-yy*sin(f(a));
    		y[rt]=xx*sin(f(a))+yy*cos(f(a));
    	}else{
    		pushDown(rt);
    		if(L<=mid) update(rt<<1,l,mid,L,R,a);
    		if(R>mid) update(rt<<1|1,mid+1,r,L,R,a);
    		pushUp(rt);
    	}
    }
    
    int main()
    {
    	int n,m;
    	bool first=true;
    	while(~scanf("%d%d",&n,&m))
    	{
    		if(!first) puts("");
    		first=false;
    		build(1,0,n-1);
    		for(int i=0;i<n;++i)
    			angle[i]=180;
    		int a,b;
    		while(m--){
    			scanf("%d%d",&a,&b);
    			update(1,0,n-1,a,n-1,b-angle[a-1]);
    			angle[a-1]=b;
    			printf("%.2lf %.2lf
    ",x[1],y[1]);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    从输入URL到页面加载发生了什么
    JS常用操作方法图表
    前端面试技巧与技术栈准备梳理
    ES6学习笔记(二)—— 通过ES6 Module看import和require区别
    我所理解的event loop
    在npm上发布一个自己的包
    微信小程序--登录流程梳理
    CSS3动画和JS动画的比较
    基于Inception搭建MySQL SQL审核平台Yearing
    MySQL数据库主从切换脚本自动化
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5715392.html
Copyright © 2011-2022 走看看