• 【题解】[Codeforces 438D] The Child and Sequence【线段树 均摊数据结构】


    题目链接

    题意

    维护序列:

    • 区间求和;
    • 单点加;
    • 区间开根并下取整。

    (n,mleq 10^5)(a_ileq 10^9)

    题解

    注意到开根并下取整的操作会很快让 (a_i) 变为 (1)。因此维护区间最大值,对于操作 3,(max a_{[l..r]}=1) 则忽略,否则暴力递归修改。

    复杂度 (O(nlog nlog a_i))

    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    const int BUF_LEN=1<<19;
    struct FastIO{
        char bufi[BUF_LEN+10],*PTi=bufi+BUF_LEN,*PTENDi=bufi+BUF_LEN;
        inline char gc(){
            (PTi==PTENDi)&&(bufi[fread(bufi,1,BUF_LEN,stdin)]=0,PTi=bufi);
            return *(PTi++);
        }
        char bufo[BUF_LEN+10],*PTo=bufo,*PTENDo=bufo+BUF_LEN;
        inline void pc(char c){
            (PTo==PTENDo)&&(fwrite(bufo,1,BUF_LEN,stdout),PTo=bufo);
            *(PTo++)=c;
        }
        void flush(){
            fwrite(bufo,1,PTo-bufo,stdout);
            PTo=bufo;
        }
        ~FastIO(){
            flush();
        }
    
        template<class T>inline void getint(T &x=0){
            char c=gc();
            int f=1;x=0;
            while(c<'0'||c>'9'){
                if(c=='-')f=-1;
                c=gc();
            }
            while(c>='0'&&c<='9'){
                x=x*10+c-'0'; 
                c=gc();
            }
            if(f==-1)x=-x;
        }
        operator int(){
            int v;getint(v);return v;
        }
        operator long long(){
            long long v;getint(v);return v;
        }
        template<class T>inline void putint(T x=0,char sep=' '){
            char tmp[20],len=0;
            if(x<0)pc('-'),x=-x;
            if(x==0){ pc('0');pc(sep);return; }
            while(x)tmp[len++]=x%10,x/=10;
            for(int i=len-1;~i;--i)pc(tmp[i]|'0');
            pc(sep);
        }
    }io;
    #define ll long long
    const int N=1e5+10;
    int t[N<<2];
    ll tt[N<<2];
    void pushup(int x){ t[x]=max(t[x<<1],t[x<<1|1]); tt[x]=tt[x<<1]+tt[x<<1|1]; }
    void modify(int l,int r,int k,int x,int nl,int nr){
        if(nr<l||nl>r)return;
        if(l<=nl&&nr<=r){
            if(nl==nr){
                t[x]%=k;
                tt[x]%=k;
                return;
            }
            int mid=nl+nr>>1;
            if(t[x<<1]>=k)modify(l,r,k,x<<1,nl,mid);
            if(t[x<<1|1]>=k)modify(l,r,k,x<<1|1,mid+1,nr);
            pushup(x);
        }else{
            int mid=nl+nr>>1;
            modify(l,r,k,x<<1,nl,mid);
            modify(l,r,k,x<<1|1,mid+1,nr);
            pushup(x);
        }
    }
    void modify(int p,int v,int x,int l,int r){
        if(l==r){t[x]=tt[x]=v;return;}
        int mid=l+r>>1;
        if(p<=mid)modify(p,v,x<<1,l,mid);
        else modify(p,v,x<<1|1,mid+1,r);
        pushup(x);
    }
    ll query(int l,int r,int x,int nl,int nr){
        if(nr<l||nl>r)return 0;
        if(l<=nl&&nr<=r)return tt[x];
        int mid=nl+nr>>1;
        return query(l,r,x<<1,nl,mid)+query(l,r,x<<1|1,mid+1,nr);
    }
    int a[N];
    void build(int x,int l,int r){
        if(l==r){
            t[x]=tt[x]=a[l];
            return;
        }
        int mid=l+r>>1;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
        pushup(x);
    }
    
    int main(){
        int n=io,m=io;
        for(int i=1;i<=n;i++)a[i]=io;
        build(1,1,n);
        while(m--){
            int op=io;
            if(op==1){
                int l=io,r=io;
                io.putint(query(l,r,1,1,n),'
    ');
            }
            if(op==2){
                int l=io,r=io,k=io;
                modify(l,r,k,1,1,n);
            }
            if(op==3){
                int p=io,v=io;
                modify(p,v,1,1,n);
            }
        }
    }
    
    
  • 相关阅读:
    nyoj--325--zb的生日(简单dp)
    nyoj--124--中位数(水题)
    nyoj--90--整数划分(母函数)
    nyoj--18--The Triangle(dp水题)
    CodeForces ---596B--Wilbur and Array(贪心模拟)
    nyoj--1023--还是回文(动态规划)
    poj--3984--迷宫问题(bfs+路径记录)
    Netty(4)Stream by codec(粘包与拆包)
    Netty(1-1)Discard
    Netty:option和childOption参数设置说明
  • 原文地址:https://www.cnblogs.com/wallbreaker5th/p/14251337.html
Copyright © 2020-2023  润新知