codeforces438 D. The Child and Sequence

This idea was used in the 2020 Weihai Regional Competition G. Caesar Cipher (if you
encounter the template question today, please write it again.

D. The Child and Sequence

Interval modulo operation template question
There is a formula x% p <x 2 (x> p) x\%p<\frac{x}{2}(x>p)x%p<2x(x>p ) Therefore, for each number at most modulo log times, if we keep modifying the value of each number, modify at mostmlog (ai) mlog(a_i)m l o g ( ai) Times, record the maximum value of the interval and judge whether it is recursive (paper cut).
Time complexitynlognlogai nlognloga_in l o g n l o g ai

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<random>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=998244353;
const int N=100010;
struct node
{
    
    
    int l,r;
    ll sum,mx;
}tree[N<<2];
int n,m;
ll a[N];
void pushup(int u)
{
    
    
    tree[u].mx=max(tree[u<<1].mx,tree[u<<1|1].mx);
    tree[u].sum=tree[u<<1].sum+tree[u<<1|1].sum;
}
void build(int u,int l,int r)
{
    
    
    tree[u]={
    
    l,r};
    if(l==r) 
    {
    
    
        tree[u].sum=tree[u].mx=a[l];
        return;
    }
    int mid=l+r>>1;
    build(u<<1,l,mid);build(u<<1|1,mid+1,r);
    pushup(u);
}
void modify1(int u,int l,int r,ll mod)
{
    
    
    if(tree[u].mx<mod) return;
    if(tree[u].l==tree[u].r) 
    {
    
    
        tree[u].sum%=mod;
        tree[u].mx%=mod;
        return;
    }
    int mid=tree[u].l+tree[u].r>>1;
    if(l<=mid) modify1(u<<1,l,r,mod);
    if(r>mid) modify1(u<<1|1,l,r,mod);
    pushup(u);
}
void modify2(int u,int pos,ll v)
{
    
    
    if(tree[u].l==tree[u].r) 
    {
    
    
        tree[u].mx=tree[u].sum=v;
        return;
    }
    int mid=tree[u].l+tree[u].r>>1;
    if(pos<=mid) modify2(u<<1,pos,v);
    else modify2(u<<1|1,pos,v);
    pushup(u);
}
ll query(int u,int l,int r)
{
    
    
    if(tree[u].l>=l&&tree[u].r<=r) return tree[u].sum;
    
    ll v=0;
    int mid=tree[u].l+tree[u].r>>1;
    if(l<=mid) v+=query(u<<1,l,r);
    if(r>mid) v+=query(u<<1|1,l,r);
    return v;
}
int main()
{
    
    
    //IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
    
    
        cin>>n>>m;
        for(int i=1;i<=n;i++) cin>>a[i];
        build(1,1,n);
        while(m--)
        {
    
    
            int op,l,r;
            cin>>op>>l>>r;
            if(op==1)
                cout<<query(1,l,r)<<'\n';
            else if(op==2)
            {
    
    
                ll x;
                cin>>x;
                modify1(1,l,r,x);
            }
            else
                modify2(1,l,r);
        }
    }
    return 0;
}

The root sign of the interval and the modulus of the interval do not satisfy the nature of the interval, but can be modified violently because the total number of operations is relatively small.

Guess you like

Origin blog.csdn.net/Fighting_Peter/article/details/110290530