• BZOJ2636: crisis(可持久化线段树)


    传送门:

    解题思路:

    题目描述是一大坑点,cancel后面是直接加ask或者redo的。

    那么就可以愉快地可持久化了。

    注意需要支持区间修改,那么就只需要在再次更新这个点的时候将标记储存在新的儿子中。

    最后由下至上询问就好了。

    代码:

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 typedef double dnt;
      6 const double eps=1e-7;
      7 struct trnt{
      8     int ls;
      9     int rs;
     10     double dltx,dlty;
     11     double alpha;
     12     bool lunked;
     13 }tr[3000000];
     14 struct pnt{
     15     double x,y;
     16     void insert(void)
     17     {
     18         scanf("%lf%lf",&x,&y);
     19         return ;
     20     }
     21 }p[100000];
     22 int siz;
     23 int cnt;
     24 int n,m;
     25 char cmd[1000];
     26 int root[1000000];
     27 void move(int spc,double dx,double dy)
     28 {
     29     tr[spc].dltx+=dx;
     30     tr[spc].dlty+=dy;
     31     return ;
     32 }
     33 void patrol(int spc,double beta)
     34 {
     35     tr[spc].alpha+=beta;
     36     double nx,ny,x,y;
     37     x=tr[spc].dltx,y=tr[spc].dlty;
     38     nx=x*cos(beta)-y*sin(beta);
     39     ny=y*cos(beta)+x*sin(beta);
     40     tr[spc].dltx=nx;
     41     tr[spc].dlty=ny;
     42     return ;
     43 }
     44 void lunk(int spc)
     45 {
     46     tr[spc].alpha=tr[spc].dltx=tr[spc].dlty=0;
     47     tr[spc].lunked=true;
     48     return ;
     49 }
     50 void pushdown(int spc,int lst)
     51 {
     52     tr[++siz]=tr[tr[lst].ls];
     53     tr[spc].ls=siz;
     54     tr[++siz]=tr[tr[lst].rs];
     55     tr[spc].rs=siz;
     56     if(tr[spc].lunked)
     57     {
     58         lunk(tr[spc].ls);
     59         lunk(tr[spc].rs);
     60     }
     61     patrol(tr[spc].ls,tr[spc].alpha);
     62     patrol(tr[spc].rs,tr[spc].alpha);
     63     move(tr[spc].ls,tr[spc].dltx,tr[spc].dlty);
     64     move(tr[spc].rs,tr[spc].dltx,tr[spc].dlty);
     65     tr[spc].lunked=false;
     66     tr[spc].alpha=tr[spc].dltx=tr[spc].dlty=0;
     67     return ;
     68 }
     69 void build(int l,int r,int &spc)
     70 {
     71     spc=++siz;
     72     if(l==r)return ;
     73     int mid=(l+r)>>1;
     74     build(l,mid,tr[spc].ls);
     75     build(mid+1,r,tr[spc].rs);
     76     return ;
     77 }
     78 void Move(int l,int r,int ll,int rr,int spc,int lst,double dx,double dy)
     79 {
     80     if(!spc)return ;
     81     if(ll>r||l>rr)return ;
     82     if(ll<=l&&r<=rr)
     83     {
     84         move(spc,dx,dy);
     85         return ;
     86     }
     87     int mid=(l+r)>>1;
     88     pushdown(spc,lst);
     89     Move(l,mid,ll,rr,tr[spc].ls,tr[lst].ls,dx,dy);
     90     Move(mid+1,r,ll,rr,tr[spc].rs,tr[lst].rs,dx,dy);
     91     return ;
     92 }
     93 void Patrol(int l,int r,int ll,int rr,int spc,int lst,double beta)
     94 {
     95     if(!spc)return ;
     96     if(ll>r||l>rr)return ;
     97     if(ll<=l&&r<=rr)
     98     {
     99         patrol(spc,beta);
    100         return ;
    101     }
    102     int mid=(l+r)>>1;
    103     pushdown(spc,lst);
    104     Patrol(l,mid,ll,rr,tr[spc].ls,tr[lst].ls,beta);
    105     Patrol(mid+1,r,ll,rr,tr[spc].rs,tr[lst].rs,beta);
    106     return ;
    107 }
    108 void Lunk(int l,int r,int ll,int rr,int spc,int lst)
    109 {
    110     if(!spc)return ;
    111     if(ll>r||l>rr)return ;
    112     if(ll<=l&&r<=rr)
    113     {
    114         lunk(spc);
    115         return ;
    116     }
    117     int mid=(l+r)>>1;
    118     pushdown(spc,lst);
    119     Lunk(l,mid,ll,rr,tr[spc].ls,tr[lst].ls);
    120     Lunk(mid+1,r,ll,rr,tr[spc].rs,tr[lst].rs);
    121     return ;
    122 }
    123 void query(int l,int r,int spc,int pos,double &x,double &y)
    124 {
    125     if(!spc)return ;
    126     if(l>r)return ;
    127     int mid=(l+r)>>1;
    128     if(pos<=mid)query(l,mid,tr[spc].ls,pos,x,y);
    129     else        query(mid+1,r,tr[spc].rs,pos,x,y);
    130     if(tr[spc].lunked)x=y=0;
    131     if(fabs(tr[spc].alpha)>eps)
    132     {
    133         double nx,ny;
    134         nx=x*cos(tr[spc].alpha)-y*sin(tr[spc].alpha);
    135         ny=y*cos(tr[spc].alpha)+x*sin(tr[spc].alpha);
    136         x=nx,y=ny;
    137     }
    138     x+=tr[spc].dltx;
    139     y+=tr[spc].dlty;
    140     return ;
    141 }
    142 int main()
    143 {
    144 //    freopen("zoo.in","r",stdin);
    145 //    freopen("zoo.out","w",stdout);
    146     scanf("%d",&n);
    147     for(int i=1;i<=n;i++)p[i].insert();
    148     scanf("%d",&m);
    149     cnt=1;
    150     build(1,n,root[cnt]);
    151     while(m--)
    152     {
    153         scanf("%s",cmd+1);
    154         if(cmd[1]=='M')
    155         {
    156             int l,r;
    157             scanf("%d%d",&l,&r);
    158             if(l>r)std::swap(l,r);
    159             double dx,dy;
    160             scanf("%lf%lf",&dx,&dy);
    161             tr[++siz]=tr[root[cnt]];
    162             root[++cnt]=siz;
    163             Move(1,n,l,r,root[cnt],root[cnt-1],dx,dy);
    164         }
    165         if(cmd[1]=='P')
    166         {
    167             int l,r;
    168             scanf("%d%d",&l,&r);
    169             double beta;
    170             scanf("%lf",&beta);
    171             if(l>r)std::swap(l,r);
    172             tr[++siz]=tr[root[cnt]];
    173             root[++cnt]=siz;
    174             Patrol(1,n,l,r,root[cnt],root[cnt-1],beta);
    175         }
    176         if(cmd[1]=='L')
    177         {
    178             int l,r;
    179             scanf("%d%d",&l,&r);
    180             if(l>r)std::swap(l,r);
    181             tr[++siz]=tr[root[cnt]];
    182             root[++cnt]=siz;
    183             Lunk(1,n,l,r,root[cnt],root[cnt-1]);
    184         }
    185         if(cmd[1]=='C')
    186         {
    187             int a;
    188             scanf("%d",&a);
    189             cnt-=a;
    190         }
    191         if(cmd[1]=='R')
    192         {
    193             int a;
    194             scanf("%d",&a);
    195             cnt+=a;
    196         }
    197         if(cmd[1]=='A')
    198         {
    199             int pos;
    200             scanf("%d",&pos);
    201             double x=p[pos].x,y=p[pos].y;
    202             query(1,n,root[cnt],pos,x,y);
    203             printf("%.6lf %.6lf
    ",x,y);
    204         }
    205     }
    206     return 0;
    207 }
  • 相关阅读:
    uniapp请求拦截
    stellar视差插件
    fullpage全屏插件应用
    fullpage全屏插件简介
    WdatePicker日期插件
    Ueditor富文本编辑器
    layer弹出层
    验证码绘制
    Ajax跨域访问
    JQuery封装的ajax方法
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10462745.html
Copyright © 2020-2023  润新知