• hdu 3954 level up 线段树区间维护


    不绕弯子,线段树区间值维护。

    每个区间应记录的值,lazy,val[12],val数组当中记录的是该区间当中每一个级数最大的经验值,如果此时经验值能够使得英雄升级,在一段区间当中有某个结点需要更新,此时我们如果用update操作的话,就要更新到最底层,那么此时线段树就没有意义,所以现在我们必须要控制一下, 只更新升级了的区间,那么我们就避免了更新一些不必要的点,因为当区间中的英雄级数不变的时候,经验累加的规则是不会改变的,所以只要精心敲一下其中的pushdown就ok了。

    在向下的更新当中,最终要的是,更新了底层的话,上层也必须要更新,所以要特别注意,总结线段树的经验,其实最要紧的就是心要够细,如果心浮气躁还是先静一下再敲吧。。。

    View Code
      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 
      6 const int N = 11111;
      7 const int INF=((1<<30)-1);
      8 
      9 struct node
     10 {
     11     int l,r;
     12     int lazy;
     13     int val[12];
     14 } tre[N<<2];
     15 
     16 int le[12],k;
     17 
     18 int upgrade(int lev,int ep)
     19 {
     20     while (lev<k)
     21     {
     22         if (ep<le[lev]) break;
     23         else lev++;
     24     }
     25     return lev;
     26 }
     27 
     28 int Max(int a,int b)
     29 {
     30     return a>b?a:b;
     31 }
     32 
     33 void PushUp(int rt)
     34 {
     35     for(int i=1; i<=k; i++)
     36         tre[rt].val[i]=Max(tre[rt<<1].val[i],tre[rt<<1|1].val[i]);
     37 }
     38 
     39 void build(int rt,int l,int r)
     40 {
     41     tre[rt].l=l; tre[rt].r=r;
     42     memset(tre[rt].val,-1,sizeof(tre[rt].val));
     43     tre[rt].lazy=tre[rt].val[1]=0;
     44     if(l==r) return ;
     45     int m=(r+l)>>1;
     46     build(rt<<1,l,m);
     47     build(rt<<1|1,m+1,r);
     48 }
     49 
     50 void PushDown(int rt)
     51 {
     52     if (tre[rt].l>=tre[rt].r) return ;
     53     if(tre[rt].lazy>0)
     54     {
     55         int t1=rt<<1;
     56         int t2=t1|1;
     57         int flag1=0,flag2=0;
     58         int v=tre[rt].lazy;
     59         tre[t1].lazy+=v;
     60         tre[t2].lazy+=v;
     61         tre[rt].lazy=0;
     62         for(int i=k; i>0; i--)
     63         {
     64             if(tre[t1].val[i]>=0)
     65             {
     66                 tre[t1].val[i]+=i*v;
     67                 if(tre[t1].val[i]>=le[i]&&i!=k)
     68                 {
    
     69                     int tmp=upgrade(i,tre[t1].val[i]);
     70                     if (tmp!=i)
     71                     {
     72                         tre[t1].val[tmp]=Max(tre[t1].val[tmp],tre[t1].val[i]);
     73                         tre[t1].val[i]=-1;
     74                         flag1=1;
     75                     }
     76                 }
     77             }
     78             if(tre[t2].val[i]>=0)
     79             {
     80                 tre[t2].val[i]+=i*v;
     81                 if(tre[t2].val[i]>=le[i]&&i!=k)
     82                 {
     83                     int tmp=upgrade(i,tre[t2].val[i]);
     84                     if (tmp!=i)
     85                     {
     86                         tre[t2].val[tmp]=Max(tre[t2].val[tmp],tre[t2].val[i]);
     87                         tre[t2].val[i]=-1;
     88                         flag2=1;
     89                     }
     90                 }
     91             }
     92         }
     93         if(flag1) PushDown(t1);
     94         if(flag2) PushDown(t2);
     95         PushUp(rt);
     96     }
     97 }
     98 
     99 void update(int rt,int l,int r,int L,int R,int v)
    100 {
    101     if(L<=l&&r<=R)
    102     {
    103         int flag=0;
    104         for (int i=k; i>0; i--)
    105         {
    106             if (tre[rt].val[i]>=0)
    107             {
    108                 tre[rt].val[i]+=i*v;
    109                 if (tre[rt].val[i]>=le[i]&&i!=k)
    110                 {
    111                     flag=1;
    112                     int tmp=upgrade(i,tre[rt].val[i]);
    113                     if (tmp!=i)
    114                     {
    115                      tre[rt].val[tmp]=Max(tre[rt].val[tmp],tre[rt].val[i]);
    116                      tre[rt].val[i]=-1;
    117                     }
    118                 }
    119             }
    120         }
    121         tre[rt].lazy+=v;
    122         if (flag) PushDown(rt);
    123         return ;
    124     }
    125     PushDown(rt);
    126     int m=(r+l)>>1;
    127     if(L<=m)update(rt<<1,l,m,L,R,v);
    128     if(R>m) update(rt<<1|1,m+1,r,L,R,v);
    129     PushUp(rt);
    130 }
    131 
    132 int query(int rt,int l,int r,int L,int R)
    133 {
    134     if(L<=l&&r<=R)
    135     {
    136         for (int i=k; i>0; i--)
    137         {
    138             if (tre[rt].val[i]>=0) return tre[rt].val[i];
    139         }
    140     }
    141     if (l==r) return 0;
    142     PushDown(rt);
    143     int m=(r+l)>>1;
    144     int ans=0;
    145     if(L<=m)ans=Max(ans,query(rt<<1,l,m,L,R));
    146     if(R>m) ans=Max(ans,query(rt<<1|1,m+1,r,L,R));
    147     return ans;
    148 }
    149 
    150 int main()
    151 {
    152     int t,n,m,a,b,v,T=0;
    153     scanf("%d",&t);
    154     char temp[5];
    155     while(t--)
    156     {
    157         scanf("%d%d%d",&n,&k,&m);
    158         build(1,1,n);
    159         for(int i=1; i<k; i++)scanf("%d",&le[i]);
    160         le[k]=INF;
    161         printf("Case %d:\n",++T);
    162         for(int i=0; i<m; i++)
    163         {
    164             scanf("%s",&temp);
    165             if(temp[0]=='W')
    166             {
    167                 scanf("%d%d%d",&a,&b,&v);
    168                 update(1,1,n,a,b,v);
    169             }
    170             else
    171             {
    172                 scanf("%d%d",&a,&b);
    173                 int tmp=query(1,1,n,a,b);
    174                 printf("%d\n",tmp);
    175             }
    176         }
    177         printf("\n");
    178     }
    179     return 0;
    180 }
  • 相关阅读:
    _I、_O、_IO的含义
    ARM启动代码中_main 与用户主程序main()的区别
    ARM汇编程序中的伪指令
    oracle密码过期问题
    等待界面-调转页面前button篇
    等待效果
    winfrom中Application.Restart()
    自动刷新处理
    泛微E8二次开发
    我的菜园子
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/2742965.html
Copyright © 2020-2023  润新知