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

  • 相关阅读:
    SQL Server CheckPoint的几个误区
    MongoDB集群与LBS应用系列(一)
    也来“玩”Metro UI之磁贴
    Python基础:函数式编程
    ASP.NET MVC 用户登录Login
    巧用 .NET 中的「合并运算符」获得 URL 中的参数
    Razor.js,基于JavaScript的Razor实现
    大话数据结构-排序
    hdu 1498
    3.7 检测两个表中是否有相同的数据
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9784113.html
Copyright © 2011-2022 走看看