zoukankan      html  css  js  c++  java
  • CSU OJ2151 集训难度

    小L正在组织acm暑假集训,但众所周知,暑假集训的萌新中有OI神犇,也有暑假才开始学算法的萌新,如果统一集训的难度,无法很好地让萌新们得到训练,所以小L想了一个办法,根据每次测试的情况,改变萌新们的集训难度。现在将萌新们编号为1到n,最初萌新们的集训难度为v0,测试后有两种操作,第一种是某一区间的萌新的集训难度同时提高,另一种是将某一段区间的萌新的集训难度变为同一个数,同时,Wells希望在某次调整难度之后,知道某一段区间的萌新的集训难度之和,由于小L比较鶸,他并不知道如何快速解决这个问题,你能帮帮他嘛?

     

    Input

    第一行三个数n,m,v0 表示有n名萌新和m次调整,初始时全部萌新的集训难度都为v0

    第2~m+1行 每行三个数或四个数

    0 x y v 表示把 [x,y]区间内的萌新的集训难度都增加v

    1 x y v 表示把 [x,y]区间内的萌新的集训难度都变为v

    2 x y表示询问[x,y]区间内萌新的集训难度之和

    0<n,m<=10^5, |v|<=10^5

    Output

    每个询问一行,输出答案

    Sample Input

    3 5 0
    0 1 3 1
    1 2 3 2
    2 1 1  
    2 2 2
    2 2 3

    Sample Output

    1
    2
    4
    

    Hint

     题解:线段树基本操作,区间加上一个数,区间变为一个数,区间和;

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define N 100001
      4 using namespace std;
      5 int n,m,x,y;
      6 long long z,val,ans;
      7 struct node
      8 {
      9     int l,r,siz;
     10     long long set,add,sum;
     11     bool v;
     12 } tree[N<<2]; 
     13 
     14 void build(int k,int l,int r)
     15 {
     16     tree[k].l=l; tree[k].r=r; tree[k].siz=r-l+1;
     17     if(l==r) 
     18     {
     19         tree[k].sum=val; 
     20         return ;
     21     }
     22     int mid=l+r>>1;
     23     build(k<<1,l,mid);
     24     build(k<<1|1,mid+1,r);
     25     tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
     26 }
     27 
     28 void pushup(int k)
     29 {
     30     tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
     31 }
     32 
     33 void pushdown_set(int k)
     34 {
     35     tree[k<<1].add=tree[k<<1|1].add=0;
     36     tree[k<<1].set=tree[k<<1|1].set=tree[k].set;
     37     tree[k<<1].v=tree[k<<1|1].v=true;
     38     tree[k<<1].sum=tree[k<<1].siz*tree[k].set;
     39     tree[k<<1|1].sum=tree[k<<1|1].siz*tree[k].set;
     40     tree[k].v=false; tree[k].set=0;
     41 }
     42 
     43 void pushdown_add(int k)
     44 {
     45     tree[k<<1].sum+=tree[k<<1].siz*tree[k].add;
     46     tree[k<<1|1].sum+=tree[k<<1|1].siz*tree[k].add;
     47     tree[k<<1].add+=tree[k].add; 
     48     tree[k<<1|1].add+=tree[k].add;
     49     tree[k].add=0;
     50 }
     51 
     52 void Set(int k,int l,int r,long long z)//区间修改为某个值 
     53 {
     54     if(tree[k].l>=l&&tree[k].r<=r)
     55     {
     56         tree[k].set=z; tree[k].v=true;
     57         tree[k].sum=z*tree[k].siz;
     58         tree[k].add=0;
     59         return;
     60     }
     61     if(tree[k].v) pushdown_set(k);
     62     if(tree[k].add) pushdown_add(k);
     63     int mid=tree[k].l+tree[k].r>>1;
     64     if(l<=mid) Set(k<<1,l,r,z);
     65     if(r>mid) Set(k<<1|1,l,r,z);
     66     pushup(k);
     67 }
     68 
     69 void Add(int k,int l,int r,long long z)//区间加上某个值 
     70 {
     71     if(tree[k].l>=l&&tree[k].r<=r)
     72     {
     73         tree[k].add+=z;
     74         tree[k].sum+=z*tree[k].siz;
     75         return;
     76     }
     77     if(tree[k].v) pushdown_set(k);
     78     if(tree[k].add) pushdown_add(k);
     79     int mid=tree[k].l+tree[k].r>>1;
     80     if(l<=mid) Add(k<<1,l,r,z);
     81     if(r>mid) Add(k<<1|1,l,r,z);
     82     pushup(k);
     83 } 
     84 
     85 void query(int k,int l,int r)
     86 {
     87     if(tree[k].l>=l&&tree[k].r<=r)
     88     {
     89         ans+=tree[k].sum;
     90         return;
     91     }
     92     if(tree[k].v) pushdown_set(k);
     93     if(tree[k].add) pushdown_add(k);
     94     int mid=tree[k].l+tree[k].r>>1;
     95     if(l<=mid) query(k<<1,l,r);
     96     if(r>mid) query(k<<1|1,l,r);
     97 }
     98 int main()
     99 {
    100     scanf("%d%d%lld",&n,&m,&val);
    101     build(1,1,n);
    102     while(m--)
    103     {
    104         int temp;
    105         scanf("%d",&temp);
    106         if(temp==0)
    107         {
    108             scanf("%d%d%lld",&x,&y,&z);
    109             Add(1,x,y,z);
    110         }
    111         else if(temp==1)
    112         {
    113             scanf("%d%d%lld",&x,&y,&z);
    114             Set(1,x,y,z);
    115         }
    116         else
    117         {
    118             scanf("%d%d",&x,&y);
    119             ans=0;
    120             query(1,x,y);
    121             printf("%lld
    ",ans);
    122         }
    123         
    124     }
    125 }

    参考代码:

  • 相关阅读:
    mac 环境下adb的安装
    iOS开发Swift版本
    UILabel-Swift
    Android应用上架
    Android应用开发
    andriod
    Android 6.0 更新包与已安装应用的签名不一致
    苹果手机怎么录屏 iOS12设置录屏
    Siri语音唤醒的开启与语音矫正
    Git的工作流程
  • 原文地址:https://www.cnblogs.com/csushl/p/9498430.html
Copyright © 2011-2022 走看看