• 【线段树】3操作线段树,很裸


    支持将某一区间设为x,将某一区间加x,查询区间的和。

    题目为 小明学求和II


     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #define mn 100001
     5 #define INF -1000001
     6 using namespace std;
     7 
     8 int n,m,b[mn],t,L,R,c;
     9 long long sum[30*mn],add[30*mn],set[30*mn];
    10 
    11 void buildtree(int k,int l,int r){
    12     set[k]=INF;
    13     int mid=(l+r)/2;
    14     if (l==r) sum[k]=set[k]=b[l];
    15     else{
    16         buildtree(2*k,l,mid);
    17         buildtree(2*k+1,mid+1,r);
    18         sum[k]=sum[2*k]+sum[2*k+1];
    19     }
    20 }
    21 
    22 inline void pushdown(int k,int l,int r){
    23     int mid=(l+r)/2;
    24     if (r==l) return;
    25     if (set[k]!=INF){
    26         set[2*k]=set[2*k+1]=set[k];
    27         add[2*k]=add[2*k+1]=0;
    28         set[k]=INF;
    29     }
    30     add[2*k]+=add[k];
    31     add[2*k+1]+=add[k];
    32     add[k]=0;
    33 }
    34 
    35 inline void maintain(int k,int l,int r){
    36     if (set[k]!=INF) sum[k]=(set[k]+add[k])*(r-l+1);
    37     else sum[k]=sum[2*k]+sum[2*k+1]+add[k]*(r-l+1);
    38 }
    39 
    40 void updateadd(int k,int l,int r){
    41     int mid=(l+r)/2;
    42     if (L<=l && R>=r) add[k]+=c;
    43     else{
    44         pushdown(k,l,r);
    45         if (L<=mid) updateadd(2*k,l,mid);else maintain(2*k,l,mid);
    46         if (R>mid) updateadd(2*k+1,mid+1,r);else maintain(2*k+1,mid+1,r);
    47     }
    48     maintain(k,l,r);
    49 }
    50 
    51 void updateset(int k,int l,int r){
    52     int mid=(l+r)/2;
    53     if (L<=l && R>=r){
    54         set[k]=c;
    55         add[k]=0;
    56     }else{
    57         pushdown(k,l,r);
    58         if (L<=mid) updateset(2*k,l,mid);else maintain(2*k,l,mid);
    59         if (R>mid) updateset(2*k+1,mid+1,r);else maintain(2*k+1,mid+1,r);
    60     }
    61     maintain(k,l,r);
    62 }
    63 
    64 long long query(int k,int l,int r){
    65     long long ans=0;
    66     int mid=(l+r)/2;
    67     if (L<=l && R>=r) return sum[k];
    68     else if (set[k]!=INF) return (long long)(set[k]+add[k])*(min(R,r)-max(L,l)+1);
    69     else{
    70         if (L<=mid) ans+=query(2*k,l,mid);
    71         if (R>mid) ans+=query(2*k+1,mid+1,r);
    72         ans+=add[k]*(min(R,r)-max(L,l)+1);
    73         return ans;
    74     }
    75 }
    76 
    77 int main(){
    78     scanf("%d%d",&n,&m);
    79     for (int i=1;i<=n;i++) scanf("%d",&b[i]);
    80     buildtree(1,1,n);
    81     for (int i=1;i<=m;i++){
    82         scanf("%d",&t);
    83         if (t==1){
    84             scanf("%d%d%d",&L,&R,&c);
    85             updateadd(1,1,n);
    86         }else if (t==2){
    87             scanf("%d%d%d",&L,&R,&c);
    88             updateset(1,1,n);
    89         }else{
    90             scanf("%d%d",&L,&R);
    91             printf("%lld\n",query(1,1,n));
    92         }
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    <JavaScript> 组合继承
    <JavaScript> 稳妥构造函数模式与工厂模式的区别
    <JavaScript> call()、apply()、bind() 的用法
    <JavaScript>可枚举属性与不可枚举属性
    <JavaScript>闭包(closure)
    在MongoDB中实现聚合函数
    (转)如何入门 Python 爬虫
    Python爬虫实战四之抓取淘宝MM照片
    转载:十年驾车经验总结:活着,才是硬道理
    设计模式之单例模式的七种写法
  • 原文地址:https://www.cnblogs.com/XGHeaven/p/3232360.html
Copyright © 2020-2023  润新知