zoukankan      html  css  js  c++  java
  • Codeves 4279 线段树练习5

    有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)范围内

    题解:线段树基本操作,区间修改,区间加,区间求最大,最小值;

    参考代码:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define N 100001
      4 using namespace std;
      5 int n,m,x,y;
      6 long long z;
      7 long long ans;
      8 struct node
      9 {
     10     int l,r,siz;
     11     long long set,add,minn,maxn,sum;
     12     bool v;
     13 }tr[N*4]; 
     14 void up(int k)
     15 {
     16     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     17     tr[k].maxn=max(tr[k<<1].maxn,tr[k<<1|1].maxn);
     18     tr[k].minn=min(tr[k<<1].minn,tr[k<<1|1].minn);
     19 }
     20 void build(int k,int l,int r)
     21 {
     22     tr[k].l=l; tr[k].r=r; tr[k].siz=r-l+1;
     23     if(l==r) 
     24     {
     25         scanf("%d",&x);
     26         tr[k].sum=tr[k].maxn=tr[k].minn=x; 
     27         return ;
     28     }
     29     int mid=l+r>>1;
     30     build(k<<1,l,mid);
     31     build(k<<1|1,mid+1,r);
     32     up(k);
     33 }
     34 void down_set(int k)
     35 {
     36     int l=k<<1,r=k<<1|1;
     37     tr[l].add=tr[r].add=0;
     38     tr[l].set=tr[r].set=tr[k].set;
     39     tr[l].v=tr[r].v=true;
     40     tr[l].maxn=tr[r].maxn=tr[l].minn=tr[r].minn=tr[k].set;
     41     tr[l].sum=tr[l].siz*tr[k].set;
     42     tr[r].sum=tr[r].siz*tr[k].set;
     43     tr[k].v=tr[k].set=0;
     44 }
     45 void down_add(int k)
     46 {
     47     int l=k<<1,r=k<<1|1;
     48     tr[l].maxn+=tr[k].add;
     49     tr[r].maxn+=tr[k].add;
     50     tr[l].minn+=tr[k].add;
     51     tr[r].minn+=tr[k].add;
     52     tr[l].sum+=tr[l].siz*tr[k].add;
     53     tr[r].sum+=tr[r].siz*tr[k].add;
     54     tr[l].add+=tr[k].add; 
     55     tr[r].add+=tr[k].add;
     56     tr[k].add=0;
     57 }
     58 void addd(int k)
     59 {
     60     if(tr[k].l>=x&&tr[k].r<=y)
     61     {
     62         tr[k].add+=z;
     63         tr[k].maxn+=z;
     64         tr[k].minn+=z;
     65         tr[k].sum+=z*tr[k].siz;
     66         return;
     67     }
     68     if(tr[k].v) down_set(k);
     69     if(tr[k].add) down_add(k);
     70     int mid=tr[k].l+tr[k].r>>1;
     71     if(x<=mid) addd(k<<1);
     72     if(y>mid) addd(k<<1|1);
     73     up(k);
     74 } 
     75 void sett(int k)
     76 {
     77     if(tr[k].l>=x&&tr[k].r<=y)
     78     {
     79         tr[k].maxn=tr[k].minn=z;
     80         tr[k].set=z; tr[k].v=true;
     81         tr[k].sum=z*tr[k].siz;
     82         tr[k].add=0;
     83         return;
     84     }
     85     if(tr[k].v) down_set(k);
     86     if(tr[k].add) down_add(k);
     87     int mid=tr[k].l+tr[k].r>>1;
     88     if(x<=mid) sett(k<<1);
     89     if(y>mid) sett(k<<1|1);
     90     up(k);
     91 }
     92 void query(int k,int w)
     93 {
     94     if(tr[k].l>=x&&tr[k].r<=y)
     95     {
     96         if(w==1) ans+=tr[k].sum;
     97         else if(w==2) ans=max(ans,tr[k].maxn);
     98         else ans=min(ans,tr[k].minn); 
     99         return;
    100     }
    101     if(tr[k].v) down_set(k);
    102     if(tr[k].add) down_add(k);
    103     int mid=tr[k].l+tr[k].r>>1;
    104     if(x<=mid) query(k<<1,w);
    105     if(y>mid) query(k<<1|1,w);
    106 }
    107 int main()
    108 {
    109     scanf("%d%d",&n,&m);
    110     build(1,1,n);
    111     char ch[8];
    112     while(m--)
    113     {
    114         scanf("%s",ch);
    115         if(ch[0]=='a')
    116         {
    117             scanf("%d%d%lld",&x,&y,&z);
    118             addd(1);
    119         }
    120         else if(ch[1]=='e')
    121         {
    122             scanf("%d%d%lld",&x,&y,&z);
    123             sett(1);
    124         }
    125         else if(ch[1]=='u')
    126         {
    127             scanf("%d%d",&x,&y);
    128             ans=0;
    129             query(1,1);
    130             printf("%lld
    ",ans);
    131         }
    132         else if(ch[1]=='a')
    133         {
    134             scanf("%d%d",&x,&y);
    135             ans=-1;
    136             query(1,2);
    137             printf("%lld
    ",ans);
    138         }
    139         else
    140         {
    141             scanf("%d%d",&x,&y);
    142             ans=1e17;
    143             query(1,3);
    144             printf("%lld
    ",ans);
    145          } 
    146     }
    147 }
    View Code
  • 相关阅读:
    软件下载链接获取方法
    【转】Linux 查看端口占用情况
    [转]SpringBoot第十集:国际化与Webjars的应用(2020最新最易懂)
    【转】Vue生命周期理解(带图的哦)
    Visual Studio 2019&WebStorm&CMD 创建vue项目
    Qt-Button使用QSS变图片按钮
    Qt-滚动条QSS样式
    Qt-鼠标点击别处隐藏widget
    OSG-修改osg鼠标中轮放大缩小的操作键
    OSG-在使用单位的kit编译osgQOpenGL时提示“语法错误:"unit"的前面应有“:””
  • 原文地址:https://www.cnblogs.com/csushl/p/9498471.html
Copyright © 2011-2022 走看看