zoukankan      html  css  js  c++  java
  • Codeforces 438D:The Child and Sequence

    简要题意:
    n个数,m种操作。
    操作一:查询区间和
    操作二:区间[l,r]对x取模
    操作三:单点赋值
    思路:

    非常经典的区间取模题。

    吕凯风出的div1的题。
    这种题的关键在于分析复杂度,本来如果没有第三个操作,会非常放心大胆地写。
    因为取模只会让值越变越小,跟区间开根基本上一个道理,该暴力的时候暴力,但是要控制暴力的次数。
    单点赋值的存在动摇了我采用这种做法的决心。
    然而在题解中,vfleaking分析了一波复杂度,其实这样做还是OK的。
    取模的性质保证了,如果一旦被取模的数大于等于模数,在取模后会严格小于原先的一半,也就是说一个数X只会发生[logX]次实际有意义的取模。
    为了保证有意义的取模,我们需要维护区间最大值,这个非常好写。
    vfleaking把每个数能发生实际取模的次数称为这个数的energy,那么初始状态下的总energy是O(Nlog(ai))的。
    维护区间最大值保证了每次实际暴力取模时,会使整个的energy之和至少减少1.
    而单点赋值,最大能让整个区间的energy之和增加O(log(ai)).
    因此整体的最大energy是O((N+M)log(ai))的。每次减小1的复杂度是均摊O(logN)(线段树深度)的。
    因此整体的复杂度是O((N+M)log(ai)logN)的。
    两个log在这道题依然是OK的能过的。

    #include<bits/stdc++.h>
    #define lson(p) p<<1
    #define rson(p) p<<1|1
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    int n,m,l,r,x,op;
    int a[maxn];
    struct node
    {
        int mx;
        ll sum;
    }b[4*maxn];
    void pushup(int p)
    {
        b[p].mx=max(b[lson(p)].mx,b[rson(p)].mx);
        b[p].sum=b[lson(p)].sum+b[rson(p)].sum;
    }
    void build(int p,int l,int r)
    {
        if (l==r) {
            b[p].mx=b[p].sum=a[l];
            return ;
        }
        int mid=(l+r)>>1;
        build(lson(p),l,mid);
        build(rson(p),mid+1,r);
        pushup(p);
    }
    void modify(int p,int l,int r,int L,int R,int v)
    {
        if (L<=l&&r<=R) {
            if (b[p].mx<v) return ;
            if (l==r) {
                b[p].mx%=v; b[p].sum%=v;
                return ;
            }
            int mid=(l+r)>>1;
            modify(lson(p),l,mid,L,R,v);
            modify(rson(p),mid+1,r,L,R,v);
            pushup(p);
            return ;
        }
        int mid=(l+r)>>1;
        if (L<=mid) modify(lson(p),l,mid,L,R,v);
        if (R>mid) modify(rson(p),mid+1,r,L,R,v);
        pushup(p);
    }
    void setVal(int p,int l,int r,int pos,int v)
    {
        if (l==r) {
            b[p].sum=b[p].mx=v;
            return ;
        }
        int mid=(l+r)>>1;
        if (pos<=mid) setVal(lson(p),l,mid,pos,v);
        else setVal(rson(p),mid+1,r,pos,v);
        pushup(p);
    }
    ll getSum(int p,int l,int r,int L,int R)
    {
        if (L<=l&&r<=R) return b[p].sum;
        int mid=(l+r)>>1;
        ll ans=0;
        if (L<=mid) ans+=getSum(lson(p),l,mid,L,R);
        if (R>mid) ans+=getSum(rson(p),mid+1,r,L,R);
        return ans;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        build(1,1,n);
        while (m--) {
            scanf("%d",&op);
            if (op==1) {
                scanf("%d%d",&l,&r);
                printf("%lld
    ",getSum(1,1,n,l,r));
            }
            else if (op==2) {
                scanf("%d%d%d",&l,&r,&x);
                modify(1,1,n,l,r,x);
            }
            else {
                scanf("%d%d",&l,&x);
                setVal(1,1,n,l,x);
            }
        }
        return 0;
    }
  • 相关阅读:
    教程:在 Visual Studio 中开始使用 Flask Web 框架
    教程:Visual Studio 中的 Django Web 框架入门
    vs2017下发现解决python运行出现‘No module named "XXX""的解决办法
    《sqlite权威指南》读书笔记 (一)
    SQL Server手工插入标识列
    hdu 3729 I'm Telling the Truth 二分图匹配
    HDU 3065 AC自动机 裸题
    hdu 3720 Arranging Your Team 枚举
    virtualbox 虚拟3台虚拟机搭建hadoop集群
    sqlserver 数据行统计,秒查语句
  • 原文地址:https://www.cnblogs.com/xyw5vplus1/p/13781342.html
Copyright © 2011-2022 走看看