zoukankan      html  css  js  c++  java
  • CodeForces-438D The Child and Sequence 线段树

    题目

    给定一个长为n的序列,要求支持区间求和,区间取余,单点修改

    题解

    首先我们有一个结论:

    (x > p)那么有((x ext{ }mod ext{ }p) <= frac{x}{2})

    所以我们在区间取余时利用区间最大值来剪枝后.

    由势能分析法易得总体复杂度是(O(nlon^2n))的.

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
        x=0;char ch;bool flag = false;
        while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
        while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    inline void read(ll &x){
        x=0;char ch;bool flag = false;
        while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
        while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    const int maxn = 100010;
    ll mx[maxn<<2],sum[maxn<<2],a[maxn];
    void build(int rt,int l,int r){
        if(l == r){
    	mx[rt] = sum[rt] = a[l];
    	return;
        }
        int mid = l+r >> 1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    ll L,R,val;
    ll query(int rt,int l,int r){
        if(L <= l && r <= R) return sum[rt];
        int mid = l+r >> 1;
        if(R <= mid) return query(rt<<1,l,mid);
        if(L >  mid) return query(rt<<1|1,mid+1,r);
        return query(rt<<1,l,mid) + query(rt<<1|1,mid+1,r);
    }
    void mod(int rt,int l,int r){
        if(l == r){
    	mx[rt] = sum[rt] = sum[rt] % val;
    	return ;
        }
        if(mx[rt] < val) return;
        int mid = l+r >> 1;
        mod(rt<<1,l,mid);mod(rt<<1|1,mid+1,r);
        mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    void search(int rt,int l,int r){
        if(L <= l && r <= R){
    	mod(rt,l,r);
    	return ;
        }
        int mid = l+r >> 1;
        if(L <= mid) search(rt<<1,l,mid);
        if(R >  mid) search(rt<<1|1,mid+1,r);
        mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    int pos;
    void modify(int rt,int l,int r){
        if(l == r){
    	mx[rt] = sum[rt] = val;
    	return ;
        }
        int mid = l+r >> 1;
        if(pos <= mid) modify(rt<<1,l,mid);
        if(pos >  mid) modify(rt<<1|1,mid+1,r);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
        mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
    }
    int main(){
        int n,m;read(n);read(m);
        for(int i=1;i<=n;++i){
    	read(a[i]);
        }build(1,1,n);
        int op;
        while(m--){
    	read(op);
    	if(op == 1){
    	    read(L);read(R);
    	    printf("%lld
    ",query(1,1,n));
    	}else if(op == 2){
    	    read(L);read(R);read(val);
    	    search(1,1,n);
    	}else if(op == 3){
    	    read(pos);read(val);
    	    modify(1,1,n);
    	}
        }
        return 0;
    }
    
    
  • 相关阅读:
    如何使用phantomJS来模拟一个HTML元素的鼠标悬停
    nodejs中使用cheerio爬取并解析html网页
    Node.js 动态网页爬取 PhantomJS 使用入门(转)
    一口一口吃掉Hibernate(五)——一对多单向关联映射
    开源 免费 java CMS
    [WinForm]dataGridView导出到EXCEL
    关键帧和动画
    uva 696
    uva 11181
    IE下target获得焦点时存在虚线的问题
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6613124.html
Copyright © 2011-2022 走看看