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有妹子啦!!!

    完结撒花!!!

  • 相关阅读:
    android学习笔记07(activity跳转,通信,及发短信)
    android学习笔记05(RadioGroup,CheckBox,Toast)
    义无返顾
    android学习笔记01(LinearLayout)
    linux远程桌面学习
    android学习笔记08(activity通信的一个实例乘法计算器)
    android学习笔记12(ProgressBar进度条初级学习)
    android学习笔记06(第一个程序)
    android学习笔记03(RelativeLayout)
    poj2886 Who Gets the Most Candies?
  • 原文地址:https://www.cnblogs.com/XLINYIN/p/11663191.html
Copyright © 2011-2022 走看看