zoukankan      html  css  js  c++  java
  • 洛谷 P3372 线段树1

    这是一道模板题

    线段树介绍https://www.cnblogs.com/nvwang123/p/10420832.html

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int m,n;
     4 int a[100001];
     5 
     6 struct node{ 
     7    int l,r;   
     8    long long w,f;  //w是区间值,f是懒标记 
     9 }xds[4*100001];   //4倍空间 
    10 
    11 //一、建树 
    12 void buid(int l,int r,int k){   
    13     xds[k].l=l; 
    14     xds[k].r=r;
    15     if(l==r){
    16         xds[k].w=a[l];  // 最底层的区间从左边开始是1,所以可以这样 
    17         return;
    18     }
    19     int m=(l+r)/2;
    20     buid(l,m,2*k);
    21     buid(m+1,r,2*k+1);
    22     xds[k].w=xds[2*k].w+xds[2*k+1].w;//不要忘记区间和上传!!特别容易忘 
    23 }
    24 
    25 
    26 //二、懒标记下传 
    27 void down(int k){
    28     xds[2*k].w+=xds[k].f*(xds[2*k].r-xds[2*k].l+1);
    29     xds[2*k+1].w+=xds[k].f*(xds[2*k+1].r-xds[2*k+1].l+1);
    30     xds[2*k].f+=xds[k].f;
    31     xds[2*k+1].f+=xds[k].f;
    32     xds[k].f=0;//易漏 
    33     }
    34 
    35 //三、区间修改    
    36 void add_(int x,int y,int k,int a){
    37     if(xds[a].l>=x&&xds[a].r<=y){
    38         xds[a].w+=(long long)k*(xds[a].r-xds[a].l+1);
    39         xds[a].f+=k;  //易漏 ,记得做懒标记 
    40         return;
    41     }
    42     if(xds[a].f) down(a);//!!! 
    43     int m=(xds[a].l+xds[a].r)/2;
    44     if(x<=m) add_(x,y,k,a*2);
    45     if(y>m)  add_(x,y,k,a*2+1);    
    46     xds[a].w=xds[a*2].w+xds[a*2+1].w;
    47 }
    48 
    49 long long ask_(int x,int y,int k)  //注意数据范围内,开int只能得70分 
    50   {
    51       if (xds[k].l>=x&&xds[k].r<=y)
    52         return xds[k].w;
    53     
    54       if(xds[k].f)    down(k);
    55       
    56       int m=(xds[k].l+xds[k].r)/2;
    57     long long ans=0;
    58       if(x<=m) ans+=ask_(x,y,k*2);
    59     if(y>m)  ans+=ask_(x,y,k*2+1);    
    60       return ans;
    61   }
    62 
    63 
    64 int main(){
    65     cin>>n>>m;
    66 
    67     for(int i=1;i<=n;i++)   cin>>a[i];
    68     buid(1,n,1);    
    69 
    70     for(int i=1;i<=m;i++){
    71         int a,x,y,k;
    72         cin>>a;
    73         if(a==1)  cin>>x>>y>>k,add_(x,y,k,1);
    74         if(a==2)  cin>>x>>y,cout<<ask_(x,y,1)<<endl;
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    更新ubuntu的源
    List<?>和List<Class<?>>区别及泛型相关
    MessageDigest类实现md5加密
    Oracle插入多个值的问题
    Oracle用户的初始化问题
    Linux 环境变量详解
    oracle数据库与实例
    Oracle基础--命令
    SQL 三种基本Join
    三种Join方法
  • 原文地址:https://www.cnblogs.com/nvwang123/p/10466599.html
Copyright © 2011-2022 走看看