zoukankan      html  css  js  c++  java
  • CodeForces 444C 节点更新求变化值的和

    http://vjudge.net/problem/viewProblem.action?id=51622

    题目大意:

    给定一列n个数字,最初赋予值1到n

    两个操作:
    1.将区间[l,r]内的数改为x,则这区间中所有数的改变值进行求和,即ans=abs(a[l]-x)+abs[a[l+1]-x).....abs(a[r]-x),但不要求输出

    2.需要将刚才要求得到的区间改变值输出出来

    这里我们利用一个color[]数组相当于给这堆数进行染色,当某个区间内的赋予的值相等时,我们可以看做有一个相同的color[]=val了,这样我们可以直接对这个区间

    利用乘法求改变值。

    这样的话,我们还需要一个数组del[]时刻记录每个量改变的差值

    sum[]数组的话就是用来保存区间改变量的和

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 #define N 100005
     5 #define LL long long
     6 #define L ls,x,mid
     7 #define R rs,mid+1,y
     8 LL color[N<<2],sum[N<<2],del[N<<2];
     9 LL abs(LL a)
    10 {
    11     return a>0?a:-a;
    12 }
    13 void push_up(int cur)
    14 {
    15     if(color[cur<<1]==color[cur<<1|1]) color[cur]=color[cur<<1];
    16     else color[cur]=0;
    17     sum[cur]=sum[cur<<1]+sum[cur<<1|1];
    18 }
    19 void push_down(int cur,int x,int y)
    20 {
    21     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
    22     if(color[cur]){
    23         color[ls]=color[rs]=color[cur];
    24         del[ls]+=del[cur],del[rs]+=del[cur];
    25         sum[ls]+=(mid-x+1)*del[cur];
    26         sum[rs]+=(y-mid)*del[cur];
    27         del[cur]=color[cur]=0;
    28     }
    29 }
    30 void build(int cur,int x,int y)
    31 {
    32     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
    33     if(x==y){
    34         color[cur]=x;
    35         sum[cur]=0;
    36         return;
    37     }
    38     color[cur]=del[cur]=0;
    39     build(L);
    40     build(R);
    41     push_up(cur);
    42 }
    43 void update(int cur,int x,int y,int s,int t,int v)
    44 {
    45     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
    46     if(x>=s&&y<=t&&color[cur]){
    47         sum[cur]+=abs(color[cur]-v)*(y-x+1);
    48         //printf("%I64d
    ",abs(color[cur]-v));
    49         del[cur]+=abs(color[cur]-v);
    50         color[cur]=v;
    51         return;
    52     }
    53     push_down(cur,x,y);
    54     if(mid>=s) update(L,s,t,v);
    55     if(mid<t) update(R,s,t,v);
    56     push_up(cur);
    57 }
    58 void query(int cur,int x,int y,int s,int t,LL &ans)
    59 {
    60     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
    61     if(x>=s&&y<=t){
    62         ans+=sum[cur];
    63         return;
    64     }
    65     push_down(cur,x,y);
    66     if(mid>=s) query(L,s,t,ans);
    67     if(mid<t) query(R,s,t,ans);
    68 }
    69 int main()
    70 {
    71     int n,m,type,l,r,x;
    72     scanf("%d%d",&n,&m);
    73     build(1,1,n);
    74     for(int i=0;i<m;i++)
    75     {
    76         scanf("%d",&type);
    77         if(type==1){
    78             scanf("%d%d%d",&l,&r,&x);
    79             update(1,1,n,l,r,x);
    80         }else{
    81             scanf("%d%d",&l,&r);
    82             LL ans=0;
    83             query(1,1,n,l,r,ans);
    84             printf("%I64d
    ",ans);
    85         }
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    关于2021-01-13爆发的incaseformat病毒相关信息收集1.2(持续更新和关注中...)
    (转)服务器UDIMM、LRDIMM、RDIMM三种内存的区别
    Shred命令 学习
    关于图片文件的元数据信息清理和时间戳修改
    关于Chrome 浏览器 “小尾巴”问题的解决办法
    CF471D MUH and Cube Walls -kmp
    UVA12467 Secret Word -kmp
    UVA12604 Caesar Cipher -kmp
    【JLOI2007】周期串
    Http协议
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3898384.html
Copyright © 2011-2022 走看看