poj2991 线段树区间更新

有种无奈叫明明有思路,却怎么也得不到Accepted。初看不知道要维护什么,完全没想法。万般无奈之下果断借鉴前人的思想,实乃向量的举一反三应用典型。由相对变量转变成绝对变量,维护向量方向和角度。根据思路敲完代码,测试也过了,兴致冲冲的交了,不出意外wrong了。然后是各种小调,交上去还是wrong,看了网上的代码居然要将角度预处理,这时才意识过来题目读错了。嘿嘿!!!


ACcode:

#include<stdio.h>
#include<math.h>
#include<iostream>
#define eps 0.005
using namespace std;

const int size=11111; 
const double PI=acos(-1.0);

int degree[size<<2],angle[size];
double sumx[size<<2],sumy[size<<2];

void change(int rt,int v)
{
       double t=(PI*(double(v))/180.0);   
       double dx=sumx[rt],dy=sumy[rt];    
       sumx[rt]=cos(t)*dx+sin(t)*dy;
       sumy[rt]=cos(t)*dy-sin(t)*dx;
}

void pushup(int rt)
{
     sumx[rt]=sumx[rt<<1]+sumx[rt<<1|1];  
     sumy[rt]=sumy[rt<<1]+sumy[rt<<1|1];   
}

void build(int rt,int l,int r)
{
     sumx[rt]=degree[rt]=0; 
     if (l==r)
     {
        angle[r]=180;
        scanf("%lf",&sumy[rt]);
        return ;         
     }    
     int m=(l+r)>>1;
     build(rt<<1,l,m);
     build(rt<<1|1,m+1,r);
     pushup(rt);
}

void pushdown(int rt)
{
     if (degree[rt])
     {
        int v=degree[rt];
        degree[rt<<1]=(degree[rt<<1]+v)%360;
        degree[rt<<1|1]=(degree[rt<<1|1]+v)%360;
        change(rt<<1,v);
        change(rt<<1|1,v);
        degree[rt]=0;
     }     
}

void update(int rt,int l,int r,int L,int v)
{
     if (L<=l)
     {
        degree[rt]=(degree[rt]+v)%360;
        change(rt,v);
        return ;
     }
     pushdown(rt);
     int m=(l+r)>>1;
     if (L<=m) update(rt<<1,l,m,L,v);
     update(rt<<1|1,m+1,r,L,v);
     pushup(rt);
}

int main()
{
    int n,q,i,p,v,flag=0;
    while (~scanf("%d %d",&n,&q))
    {
          if (flag) printf("\n");
          else flag=1;
          build(1,1,n);
          while (q--)
          {
                scanf("%d %d",&p,&v);
                update(1,1,n,p+1,angle[p]-v);   
                angle[p]=v;
                printf("%.2lf %.2lf\n",
                fabs(sumx[1])<eps?0:sumx[1],fabs(sumy[1])<eps?0:sumy[1]);
          }
    }
    return 0;     
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值