zoukankan      html  css  js  c++  java
  • codevs 4927 线段树练习5 线段树基本操作模板

    4927 线段树练习5

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
     
    题目描述 Description

    有n个数和5种操作

    add a b c:把区间[a,b]内的所有数都增加c

    set a b c:把区间[a,b]内的所有数都设为c

    sum a b:查询区间[a,b]的区间和

    max a b:查询区间[a,b]的最大值

    min a b:查询区间[a,b]的最小值

    输入描述 Input Description

    第一行两个整数n,m,第二行n个整数表示这n个数的初始值

    接下来m行操作,同题目描述

    输出描述 Output Description

    对于所有的sum、max、min询问,一行输出一个答案

    样例输入 Sample Input

    10 6

    3 9 2 8 1 7 5 0 4 6

    add 4 9 4

    set 2 6 2

    add 3 8 2

    sum 2 10

    max 1 7

    min 3 6

    样例输出 Sample Output

    49

    11

    4

    数据范围及提示 Data Size & Hint

    10%:1<n,m<=10

    30%:1<n,m<=10000

    100%:1<n,m<=100000

    保证中间结果在long long(C/C++)、int64(pascal)范围内

     ----------------------------------------------------------------------------------------------------------------

    重新温习了一遍线段树的一些基本操作,并把以前写过的代码重写了一遍。

    区间修改(增加和重设)和查询(和,最大/小值)

    为了同时实现这两个区间修改的操作,需要给每段区间分别打上两个标记tag和set,一个记录add修改,另一个记录set修改

    add修改就直接累加tag,set修改除了需要把set标记覆盖为新值之外,还需要把tag清零,具体实现看代码 

    需要注意的是pushdown(下传)的时候应该是set在前 add在后,对应前面对标记的操作(因为前面是遇到set操作时就会清空tag,所以应该是先set后tag,即先重设后增加),顺序不能颠倒

    AC代码:

      1 #include<stdio.h>
      2 #include<iostream>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 #define maxn 100010
      6 using namespace std;
      7 struct node{
      8     int l,r;
      9     int tag,set;
     10     long long sum;
     11     int ma,mi;
     12 };
     13 node tr[maxn*4];//四倍保平安 
     14 int read();
     15 void build(int,int,int);
     16 void fma(int,int,int);
     17 void add(int,int,int,int);
     18 void putdownsum(int);
     19 void putdownset(int);
     20 int n,m,sts[maxn],o;
     21 long long ans;
     22 char s1[23]={"add"},s2[23]={"set"},s3[23]={"sum"},s4[23]={"max"};
     23 bool flag,bl[maxn*4];
     24 int main(){
     25     memset(bl,0,sizeof(bl));
     26     n=read(),m=read();
     27     for(int i=1;i<=n;i++) sts[i]=read();
     28     build(1,n,1);
     29     for(int i=1;i<=m;i++){
     30         char s[23];
     31         memset(s,0,sizeof(s));
     32         scanf(" %s",s);
     33         if(!memcmp(s,s1,3)){
     34             int a=read(),b=read(),c=read();
     35             flag=true;
     36             add(a,b,c,1);
     37         }
     38         else if(!memcmp(s,s2,3)){
     39             int a=read(),b=read(),c=read();
     40             flag=false;
     41             add(a,b,c,1);
     42         }
     43         else if(!memcmp(s,s3,3)){
     44             int a=read(),b=read();
     45             ans=0;o=3;
     46             fma(a,b,1);
     47             printf("%lld
    ",ans);
     48         }
     49         else if(!memcmp(s,s4,3)){
     50             int a=read(),b=read();
     51             ans=0;o=1;
     52             fma(a,b,1);
     53             printf("%lld
    ",ans);
     54         }
     55         else{
     56             int a=read(),b=read();
     57             ans=1e15;o=2;
     58             fma(a,b,1);
     59             printf("%lld
    ",ans);
     60         }
     61     }
     62     return 0;
     63 }
     64 #define lson k<<1
     65 #define rson k<<1|1
     66 void pushup(int k){
     67     tr[k].sum=tr[lson].sum+tr[rson].sum;
     68     tr[k].ma=max(tr[lson].ma,tr[rson].ma);
     69     tr[k].mi=min(tr[lson].mi,tr[rson].mi);
     70 }
     71 void build(int l,int r,int k){
     72     tr[k].l=l;tr[k].r=r;
     73     if(l==r){
     74         tr[k].sum=tr[k].ma=tr[k].mi=sts[l];
     75         return;
     76     }
     77     int mid=(l+r)>>1;
     78     build(l,mid,lson);
     79     build(mid+1,r,rson);
     80     pushup(k);
     81 }
     82 void add(int l,int r,int x,int k){
     83     if(l<=tr[k].l&&tr[k].r<=r){
     84         if(flag){
     85             tr[k].tag+=x;
     86             tr[k].sum+=(tr[k].r-tr[k].l+1)*x;
     87             tr[k].ma+=x;
     88             tr[k].mi+=x; 
     89         }
     90         else{
     91             bl[k]=1;
     92             tr[k].tag=0;
     93             tr[k].sum=(tr[k].r-tr[k].l+1)*x;
     94             tr[k].set=tr[k].ma=tr[k].mi=x;
     95         }
     96         return;
     97     }
     98     if(bl[k]) putdownset(k);
     99     if(tr[k].tag) putdownsum(k);
    100     int mid=(tr[k].l+tr[k].r)>>1;
    101     if(l<=mid) add(l,r,x,lson);
    102     if(mid<r)  add(l,r,x,rson);
    103     pushup(k);
    104 }
    105 void putdownset(int k){
    106     tr[lson].set=tr[k].set;bl[lson]=1;
    107     tr[rson].set=tr[k].set;bl[rson]=1;
    108     tr[lson].sum=(tr[lson].r-tr[lson].l+1)*tr[k].set;
    109     tr[rson].sum=(tr[rson].r-tr[rson].l+1)*tr[k].set;
    110     tr[lson].ma=tr[k].set;tr[rson].ma=tr[k].set;
    111     tr[lson].mi=tr[k].set;tr[rson].mi=tr[k].set;
    112     tr[lson].tag=0;tr[rson].tag=0;
    113     tr[k].set=0;bl[k]=0;
    114 }
    115 void putdownsum(int k){
    116     tr[lson].tag+=tr[k].tag;
    117     tr[rson].tag+=tr[k].tag;
    118     tr[lson].sum+=(tr[lson].r-tr[lson].l+1)*tr[k].tag;
    119     tr[rson].sum+=(tr[rson].r-tr[rson].l+1)*tr[k].tag;
    120     tr[lson].ma+=tr[k].tag;tr[rson].ma+=tr[k].tag;
    121     tr[lson].mi+=tr[k].tag;tr[rson].mi+=tr[k].tag;
    122     tr[k].tag=0;
    123 }
    124 void fma(int l,int r,int k){
    125     if(l<=tr[k].l&&tr[k].r<=r){
    126         if(o==1) ans=ans>tr[k].ma?ans:tr[k].ma;
    127         else if(o==2) ans=ans>tr[k].mi?tr[k].mi:ans;
    128         else ans+=tr[k].sum;
    129         return;
    130     }
    131     if(bl[k]) putdownset(k);
    132     if(tr[k].tag) putdownsum(k);
    133     int mid=(tr[k].r+tr[k].l)>>1;
    134     if(l<=mid) fma(l,r,lson);
    135     if(mid<r)  fma(l,r,rson);
    136 }
    137 int read(){
    138     int an=0,f=1;char c=getchar();
    139     while('0'>c||c>'9'){if(c=='-')f=-1;c=getchar();}
    140     while('0'<=c&&c<='9')an=an*10+c-48,c=getchar();return an*f;
    141 }
    线段树基本操作
  • 相关阅读:
    Android的依赖注入框架:Dagger
    Android第三方开发组件
    Android 应用市场链接上传地址
    Android 开源框架以及开源项目以及连接
    Android 左右侧滑
    Android Textview 跑马灯
    Android XMPP推送
    Android多分辨率设配方案
    Android特效UI
    Android 时间的转换
  • 原文地址:https://www.cnblogs.com/lpl-bys/p/7622223.html
Copyright © 2011-2022 走看看