• NBUT 1120 Reimu's Teleport (线段树)


    题意:

      有n个格子,一开始全部面向top。接下来的每次修改F a b ,如果 a>b则将a~b之间的格子全面置为向右,否则置为向左。对于每个询问Q输出向左、top、右的数量。

    思路:

      普通线段树。每个结点中保存三个值,分别对应3个方向的数量。要设置一下lazy_tag以减少时间消耗,因为有可能Q远少于F,那么一直在更改,大多可能不需要改到,暂时不更新,询问时要用到再更新。每次一改就整个区间都是一个方向,所以当有tag时可以往下推各占多少。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 int ans[3];//答案
      4 struct node
      5 {
      6     bool tag;
      7     int num[3];
      8     node *ll,*rr;
      9     node()
     10     {
     11         tag=false;
     12         num[0]=num[1]=num[2]=0;
     13         ll=rr=0;
     14     }
     15 };
     16 
     17 node * built(int LL, int RR)
     18 {
     19     node *tmp=new(node);
     20     if(LL==RR)
     21     {
     22         tmp->num[1]=1;
     23         return tmp;
     24     }
     25     int mid=(LL+RR)>>1;
     26     tmp->ll=built(LL,mid);
     27     tmp->rr=built(mid+1,RR);
     28     tmp->num[1]+=tmp->ll->num[1]+tmp->rr->num[1];   //开始只需要更新向上的
     29     return tmp;
     30 }
     31 
     32 void modify( node *t,int LL,int RR,int mid)//专门修改统计数量
     33 {
     34     if(t->num[0])
     35     {
     36         t->ll->num[0]=mid+1-LL;
     37         t->ll->num[1]=t->ll->num[2]=0;
     38         t->rr->num[0]=RR-mid;
     39         t->rr->num[1]=t->rr->num[2]=0;
     40     }
     41     if(t->num[1])
     42     {
     43         t->ll->num[1]=mid+1-LL;
     44         t->ll->num[0]=t->ll->num[2]=0;
     45         t->rr->num[1]=RR-mid;
     46         t->rr->num[0]=t->rr->num[2]=0;
     47     }
     48     if(t->num[2])
     49     {
     50         t->ll->num[2]=mid+1-LL;
     51         t->ll->num[0]=t->ll->num[1]=0;
     52         t->rr->num[2]=RR-mid;
     53         t->rr->num[0]=t->rr->num[1]=0;
     54     }
     55 }
     56 
     57 void update(int ll,int rr,int LL,int RR,int c,node *t)
     58 {
     59     if(ll==LL&&rr==RR)
     60     {
     61         t->tag=true;
     62         if(c==0)
     63         {
     64             t->num[0]=RR-LL+1;
     65             t->num[1]=t->num[2]=0;
     66         }
     67         else
     68         {
     69             t->num[2]=RR-LL+1;
     70             t->num[0]=t->num[1]=0;
     71         }
     72         return;
     73     }
     74     int mid=(LL+RR)>>1;
     75 
     76     if(t->tag)
     77     {
     78         t->tag=false;
     79         t->ll->tag=t->rr->tag=true;
     80         modify(t,LL,RR,mid);
     81     }
     82     if(ll>mid)  //右边
     83         update(ll,rr,mid+1,RR,c,t->rr);
     84     else if(rr<=mid)    //左边
     85         update(ll,rr,LL,mid,c,t->ll);
     86     else
     87     {
     88         update(ll, mid, LL, mid, c,t->ll);
     89         update(mid+1,rr,mid+1,RR,c,t->rr);
     90     }
     91     t->num[0]=t->ll->num[0]+t->rr->num[0];
     92     t->num[1]=t->ll->num[1]+t->rr->num[1];
     93     t->num[2]=t->ll->num[2]+t->rr->num[2];
     94 }
     95 
     96 
     97 
     98 void query(int ll,int rr,int LL,int RR,node* t)
     99 {
    100     if(ll==LL && rr==RR)
    101     {
    102         ans[0]+=t->num[0];
    103         ans[1]+=t->num[1];
    104         ans[2]+=t->num[2];
    105         return;
    106     }
    107     int mid=((LL+RR)>>1);
    108     if(t->tag)
    109     {
    110         t->tag=false;
    111         t->ll->tag= t->rr->tag= true;
    112         modify(t, LL, RR, mid);
    113     }
    114 
    115     if(ll>mid)          query(ll,rr,mid+1,RR,t->rr);
    116     else if(rr<=mid)    query(ll,rr,LL,mid,t->ll);
    117     else
    118     {
    119         query(ll, mid, LL, mid, t->ll);
    120         query(mid+1,rr,mid+1,RR,t->rr);
    121     }
    122 
    123 }
    124 
    125 
    126 int main()
    127 {
    128     //freopen("e://input.txt","r",stdin);
    129     int a, t, e, r;
    130     char ch;
    131 
    132     while(cin>>a>>t)
    133     {
    134         node *tree=built(1,t); //建树
    135 
    136         for(int i=0; i<a; i++)
    137         {
    138             cin>>ch;
    139             scanf("%d %d", &e, &r);
    140             if(ch=='F')  //修改
    141             {
    142                 if(e>r) update(r, e, 1, t, 0, tree);
    143                 else    update(e, r, 1, t, 2, tree);
    144             }
    145             else        //Q 查询
    146             {
    147                 memset(ans,0,sizeof(ans));
    148                 query(e,r,1,t,tree);
    149                 printf("%d %d %d
    ",ans[0],ans[1],ans[2]);
    150             }
    151         }
    152     }
    153     return 0;
    154 }
    AC代码
  • 相关阅读:
    eclipse中的项目无法在build/classes目录下生成.class字节码
    nginx的权限问题(Permission denied)解决办法
    application/x-www-form-urlencoded、application/json、multipart/form-data、text/xml简单总结
    jackson的使用和详解
    博客园自定义样式
    java基础
    k8s
    系统服务构建运维
    私有云技术
    工程文档编写
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4538835.html
Copyright © 2020-2023  润新知