[CF 438 D] The Child and Sequence 线段树

牛客多校打到自闭。。。
签完到继续补专题

题目思路
题目给了三个要实现的功能
单线修改
区间和查询
还有将区间内叶子节点mod k

本来想用lazy_tag来做 对区间和做mod
然后查询的时候向下递归
但是有一个问题就是如果叶子结点的值本身小于k那么mod运算对它的值并不会产生影响 所以最后结果有问题

看了题解说在维护区间和的同时维护最大值
在做mod运算的时候拿k和区间最大值比较
如果区间最大值小于mod
那么本次运算对本区间的值没有影响 直接return
小于就直接单点修改

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 2e5+10;
const int inf = 0x1f1f1f1f;
const int mod = 2333;

int a[maxn];
ll t[maxn<<2],tmax[maxn<<2];

void pushup(int rt)
{
    t[rt]=t[lson]+t[rson];
    tmax[rt]=max(tmax[lson],tmax[rson]);
}

void build(int rt,int l,int r)
{
    if(l==r)
    {
        t[rt]=a[l];
        tmax[rt]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    pushup(rt);
}

void change(int p,int v,int l,int r,int rt)
{
    if(l==r)
    {
        t[rt]=v;
        tmax[rt]=v;
        return;
    }
    int mid=(l+r)>>1;
    if(p<=mid)
        change(p,v,l,mid,lson);
    else
        change(p,v,mid+1,r,rson);
    pushup(rt);
}

void update(int L,int R,int l,int r,int mod,int rt)
{
    if(tmax[rt]<mod)
    {
        //printf("t %d\n",tmax[rt]);
        return;
    }
    if(l==r)
    {
        t[rt]=t[rt]%mod;
        tmax[rt]=tmax[rt]%mod;
        return;
    }
    int mid=(l+r)>>1;
    if(L<=mid)
        update(L,R,l,mid,mod,lson);
    if(R>mid)
        update(L,R,mid+1,r,mod,rson);
    pushup(rt);
}

ll query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)
    {
        return t[rt];
    }
    int mid=(l+r)>>1;
    ll res=0;
    if(L<=mid)
        res+=query(L,R,l,mid,lson);
    if(R>mid)
        res+=query(L,R,mid+1,r,rson);
    return res;
}

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    build(1,1,n);
    while(q--)
    {
        int tp;
        scanf("%d",&tp);
        if(tp==1)
        {
           int l,r;
           scanf("%d%d",&l,&r);
           ll ans=query(l,r,1,n,1);
           printf("%lld\n",ans);
        }
        if(tp==2)
        {
            int l,r,x;
            scanf("%d%d%d",&l,&r,&x);
            update(l,r,1,n,x,1);
        }
        if(tp==3)
        {
            int l,x;
            scanf("%d%d",&l,&x);
            change(l,x,1,n,1);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/daydreamer23333/article/details/107298690