zoukankan      html  css  js  c++  java
  • mod

    mod

    题目描述

    给定一个长度为 (n) 的非负整数序列 (a),你需要支持以下操作:
    1:给定 (l,r),输出 (a[l]+a[l+1]+…+a[r])
    2:给定 (l,r,x),将 (a[l],a[l+1],…,a[r])(x) 取模。
    3:给定 (k,y),将 (a[k])修改为 (y)

    输入数据

    第一行两个整数 (n),(m)

    第二行 (n) 个整数 (a[1]~a[n])。接下来 (m) 行每行 (3)(4) 个整数表示操作。

    输出数据

    对于每个操作 (1),输出一行一个整数表示答案。

    数据范围

    对于 (40\%) 的数据, (n,m<=1000)
    对于 (100\%) 的数据,(n,m<=100000)(1<=l<=r<=n)(1<=k<=n)(1<=x<=10^9)
    (0<=a[i],y<=10^9)


    最开始只想着乱搞,结果过了,然后发现就是正解。。

    维护区间和和区间max,每次暴力取模,如果(max)比模数小,就不进那个区间。

    复杂度是(O(nlog^2n))

    为什么呢?本着**的精神,我去研究了一下势能分析,看懂了是看懂了,但我并不会用来分析这个题。

    简单说一下我的理解吧。

    注意到每次取模最少把一个数缩小一半

    所以在没有修改时总取模次数小于(nlognlog1e9)

    一次单点修改至多使时间复杂度增加(lognlog1e9)


    Code:

    #include <cstdio>
    #define ls id<<1
    #define rs id<<1|1
    #define ll long long
    const int N=1e5+10;
    int n,m,a[N];
    ll mx[N<<2],sum[N<<2];
    ll max(ll x,ll y){return x>y?x:y;}
    void updata(int id)
    {
        sum[id]=sum[ls]+sum[rs];
        mx[id]=max(mx[ls],mx[rs]);
    }
    void change(int id,int L,int R,int l,int r,ll x)
    {
        if(mx[id]<x) return;
        if(L==R){sum[id]%=x;mx[id]%=x;return;}
        int Mid=L+R>>1;
        if(r<=Mid) change(ls,L,Mid,l,r,x);
        else if(l>Mid) change(rs,Mid+1,R,l,r,x);
        else change(ls,L,Mid,l,Mid,x),change(rs,Mid+1,R,Mid+1,r,x);
        updata(id);
    }
    void change0(int id,int l,int r,int pos,ll x)
    {
        if(l==r) {sum[id]=mx[id]=x;return;}
        int mid=l+r>>1;
        if(pos<=mid) change0(ls,l,mid,pos,x);
        else change0(rs,mid+1,r,pos,x);
        updata(id);
    }
    ll query(int id,int L,int R,int l,int r)
    {
        if(l==L&&r==R) return sum[id];
        int Mid=L+R>>1;
        if(r<=Mid) return query(ls,L,Mid,l,r);
        else if(l>Mid) return query(rs,Mid+1,R,l,r);
        else return query(ls,L,Mid,l,Mid)+query(rs,Mid+1,R,Mid+1,r);
    }
    void build(int id,int l,int r)
    {
        if(l==r)
        {
            mx[id]=sum[id]=1ll*a[l];
            return;
        }
        int mid=l+r>>1;
        build(ls,l,mid),build(rs,mid+1,r);
        updata(id);
    }
    int read()
    {
        int x=0;char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
        return x;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        //freopen("lg.out","w",stdout);
        n=read(),m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        build(1,1,n);
        for(int op,l,r,x,i=1;i<=m;i++)
        {
            op=read();
            if(op==1)
            {
                l=read(),r=read();
                printf("%lld
    ",query(1,1,n,l,r));
            }
            else if(op==2)
            {
                l=read(),r=read(),x=read();
                change(1,1,n,l,r,1ll*x);
            }
            else
            {
                l=read(),x=read();
                change0(1,1,n,l,1ll*x);
            }
        }
        return 0;
    }
    

    2018.10.13

  • 相关阅读:
    HDU4628+状态压缩DP
    Javascript 去掉字符串前后空格的五种方法
    Javascript 数组之判断取值和数组取值
    ASP.NET MVC 出现错误 “The view 'XXX' or its master was not found or no view engine support”
    ASP.NET MVC 页面调整并传递参数
    ASP.NET MV3 部署网站 报"Could not load file or assembly ' System.Web.Helpers “ 错的解决方法
    ASP.NET MVC 控制器向View传值的三种方法
    CSharp 如何通过拼接XML调用存储过程来查询数据
    SQLServer : EXEC和sp_executesql的区别
    关于SQLServer2005的学习笔记—异常捕获及处理
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9784113.html
Copyright © 2011-2022 走看看