zoukankan      html  css  js  c++  java
  • The Child and Sequence

    Codeforces Round #250 (Div. 1)D:http://codeforces.com/problemset/problem/438/D

    题意:给你一个序列,然后有3种操作 1x y.表示查询[x,y]之间的区间和,2 x y z表示把[x y]内的数%z,3x y,表示把第x个数变成y。

    题解:肯定是用线段树来维护,但是一开始想不到维护什么统计量,对于区间取模,没办法用lazy标记,更新到第的话,肯定会T。后来,认为既然没办法用lazy,那么只能用别的方法来优化更新。发现每次取模之后,数都会变小,如果要取模的数比当前模数小的话,就不用取模,于是可以维护区间最大值,如果区间最大值都小于模数的话,这个区间肯定不用更新,这样来减少更新。这样的方法,其实以前也做过,就是对于一个区间内的数进行开平方操作,每个数会越开越小,到了1的时候就可以直接不开了。因此,对于线段树的区间更新来说:1如果能找到好的lazy可以标记的话,就使用lazy标记;2如果找不到就要想办法优化区间更新,让单点更新的次数变少。另外此题,自己用线段树省空间的写法,结果不熟练,一个地方写错,最后wa几发。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int N=1e5+19;
     7 int n,m;
     8 long long sum[N*4],maxn[N*4];
     9 void pushup(int rt){
    10    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    11    maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]);
    12 }
    13 void build(int l,int r,int rt){
    14     if(l==r){
    15         scanf("%I64d",&maxn[rt]);
    16         sum[rt]=maxn[rt];
    17         return;
    18     }
    19     int mid=(l+r)/2;
    20     build(l,mid,rt<<1);
    21     build(mid+1,r,rt<<1|1);
    22     pushup(rt);
    23 }
    24 void update(int l,int r,int rt,int from,int to,long long mod){
    25      if(maxn[rt]<mod)return;
    26      if(l==r){
    27         maxn[rt]%=mod;
    28         sum[rt]=maxn[rt];
    29         return;
    30      }
    31      int mid=(l+r)/2;
    32     if(mid>=to)update(l,mid,rt<<1,from,to,mod);
    33     else if(mid<from)update(mid+1,r,rt<<1|1,from,to,mod);
    34     else{
    35         update(l,mid,rt<<1,from,mid,mod);
    36         update(mid+1,r,rt<<1|1,mid+1,to,mod);
    37     }
    38   pushup(rt);
    39 }
    40 void update2(int l,int r,int rt,int pos,long long val){
    41      if(l==r){
    42         maxn[rt]=val;
    43         sum[rt]=val;
    44         return;
    45      }
    46      int mid=(l+r)/2;
    47     if(mid>=pos)update2(l,mid,rt<<1,pos,val);
    48     else update2(mid+1,r,rt<<1|1,pos,val);
    49   pushup(rt);
    50 }
    51 long long query(int l,int r,int rt,int from,int to){
    52     if(l==from&&r==to){
    53         return sum[rt];
    54     }
    55    int mid=(l+r)/2;
    56    if(mid>=to)return query(l,mid,rt<<1,from,to);
    57    else if(mid<from)return query(mid+1,r,rt<<1|1,from,to);
    58    else {
    59       return query(l,mid,rt<<1,from,mid)+query(mid+1,r,rt<<1|1,mid+1,to);
    60 
    61    }
    62 }
    63 int t,t1,t4;
    64 long long t2,t3;
    65 int main(){
    66   while(~scanf("%d%d",&n,&m)){
    67       memset(sum,0,sizeof(sum));
    68       memset(maxn,0,sizeof(maxn));
    69       build(1,n,1);
    70       for(int i=1;i<=m;i++){
    71         scanf("%d%d",&t,&t1);
    72         if(t==1){
    73             scanf("%d",&t4);
    74             printf("%I64d
    ",query(1,n,1,t1,t4));
    75       }
    76       else if(t==2){
    77         scanf("%d%I64d",&t4,&t2);
    78          update(1,n,1,t1,t4,t2);
    79       }
    80       else{
    81             scanf("%I64d",&t2);
    82         update2(1,n,1,t1,t2);
    83       }
    84     }
    85   }
    86 }
    View Code
  • 相关阅读:
    qt一些函数
    js时间字符串转时间戳
    golang学习之interface与其它类型转换
    golang学习之奇葩的time format
    windows下安装mongodb
    golang学习之struct
    golang学习之闭包
    js生成6位随机码
    golang学习之生成代码文档
    moment常用操作
  • 原文地址:https://www.cnblogs.com/chujian123/p/3870081.html
Copyright © 2011-2022 走看看