zoukankan      html  css  js  c++  java
  • 神奇脑洞题解——苦恼的Van

    传送门

    一句话题面:给定一个序列,维护两种操作。区间取模和区间求和。

    这道题不能使用Lazy标记!!!

    不是不用,是不能!!!

    mod运算不满足分配律,因此无法使用Lazy标记。

    但是如果单纯只写一个区间求值和一mod到底的mod操作,会T到你怀疑人生。

    虽然mod不满足分配律,但是mod有一个性质:如果x<mod,那么x%mod==x

    由此,我们可以维护一个区间最大值,以此来判断这个区间是否需要进行mod运算。

    AC代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int sum[400001],mx[400001];
    int n,m,a,b,c;
    int val[100001];
    int ls(int x)
    {
        return x<<1;
    }
    int rs(int x)
    {
        return x<<1|1;
    }
    void pushup(int x)
    {
        sum[x]=sum[ls(x)]+sum[rs(x)];
        mx[x]=max(mx[ls(x)],mx[rs(x)]);
    }
    void build(int x,int l,int r)
    {
        if(l==r)
        {
            sum[x]=val[l];
            mx[x]=sum[x];
            return ;
        }
        int mid=(l+r)>>1;
        build(ls(x),l,mid);
        build(rs(x),mid+1,r);
        pushup(x); 
    }
    void Mod(int x,int l,int r,int nl,int nr,int mod)
    {
        if(l==r)
        {
            sum[x]%=mod;
            mx[x]%=mod;
            return;
        }
        if(mx[x]<mod)
            return;
        int mid=(l+r)>>1;
        if(nl<=mid)
            Mod(ls(x),l,mid,nl,nr,mod);
        if(nr>mid)
            Mod(rs(x),mid+1,r,nl,nr,mod);
        pushup(x);
    }
    int Query(int x,int l,int r,int nl,int nr)
    {
        if(nl<=l&&nr>=r)
            return sum[x];
        int mid=(l+r)>>1;
        int res=0;
        if(nl<=mid)
        {
            res+=Query(ls(x),l,mid,nl,nr);
        }
        if(nr>mid)
        {
            res+=Query(rs(x),mid+1,r,nl,nr);
        }
        return res;
    }
    int LINYIN()
    {
        freopen("van_modify.in","r",stdin);
        freopen("van_modify.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&val[i]);
        }
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&a);
            if(a==0)
            {
                scanf("%d%d",&a,&b);
                printf("%d",Query(1,1,n,a,b));
            }
            else
            {
                scanf("%d%d%d",&a,&b,&c);
                Mod(1,1,n,a,b,c);
            }
        }
        return 0;
    }
    int LWH=LINYIN();
    int main()
    {
        ;
    }
    AC

    顺带一提,LINYIN有妹子啦!!!

    完结撒花!!!

  • 相关阅读:
    Linux 模块管理
    python 调试方法
    LFS(Linux From Scratch)学习
    Vim完全教程
    OpenSSL基础知识
    关于jiffies回绕以及time_after,time_before
    十分简便的APK反编译(Mac 版本号 具体解释)
    亚马逊是怎样颠覆商业软件高昂价格这座”柏林墙”的
    Android自己定义控件
    Android基础新手教程——4.1.1 Activity初学乍练
  • 原文地址:https://www.cnblogs.com/XLINYIN/p/11663191.html
Copyright © 2011-2022 走看看