Transformation HDU - 4578 (线段树,审题很重要)

本文介绍了一种通过四种不同操作来更新数组的方法:加法、乘法、赋值及求和,并提供了一段C++代码实现。这四种操作分别作用于数组的一个子区间内,涉及数组元素的加法更新、乘法更新、赋值更新以及子区间内元素的幂次求和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Yuanfang is puzzled with the question below: 
There are n integers, a 1, a 2, …, a n. The initial values of them are 0. There are four kinds of operations. 
Operation 1: Add c to each number between a x and a y inclusive. In other words, do transformation a k<---a k+c, k = x,x+1,…,y. 
Operation 2: Multiply c to each number between a x and a y inclusive. In other words, do transformation a k<---a k×c, k = x,x+1,…,y. 
Operation 3: Change the numbers between a x and a y to c, inclusive. In other words, do transformation a k<---c, k = x,x+1,…,y. 
Operation 4: Get the sum of p power among the numbers between a x and a y inclusive. In other words, get the result of a x p+a x+1 p+…+a y p

Yuanfang has no idea of how to do it. So he wants to ask you to help him. 


#include<bits/stdc++.h>

using namespace std;
#define lson i<<1,l,m
#define rson i<<1|1, m+1,r
const int mod = 10007;
const int maxn=1e5+10;

int x[maxn<<2],flag[maxn<<2];

void pushup(int i,int l,int r)
{
    if(!flag[i<<1] || !flag[i<<1|1])
        flag[i] = 0;
    else if(x[i<<1] != x[i<<1|1])
        flag[i] = 0;
    else flag[i]=1,x[i]=x[i<<1];
}

void pushdown(int i,int l,int r)
{
    if(flag[i])
    {
        flag[i<<1] = flag[i<<1|1] =1;
        x[i<<1] = x[i<<1|1] = x[i];
        flag[i]=0;
    }
}

void update(int ql,int qr,int p,int v,int i,int l,int r)
{
    if(ql<=l && qr>=r && flag[i])
    {
        if(p==1)
            x[i] = (x[i]+v)%mod;
        else if(p==2)
            x[i] = (x[i]*v)%mod;
        else x[i] = v;
        return;
    }
    pushdown(i,l,r);

    int m = (l+r)>>1;
    if(ql<=m) update(ql,qr,p,v,lson);
    if(qr>m) update(ql,qr,p,v,rson);
    pushup(i,l,r);
}
int query(int ql,int qr,int num,int i,int l,int r)
{
    if(flag[i] && ql<=l && qr>=r)
    {
        int ans=1;
        for(int j=0;j<num;j++)ans=(ans*x[i])%mod;
        ans=(ans*(r-l+1))%mod;
        return ans;
    }

    pushdown(i,l,r);

    int m = (l+r)>>1;
    int ans=0;
    if(ql<=m)ans+=query(ql,qr,num,lson);
    if(qr>m)ans+=query(ql,qr,num,rson);
    return ans%mod;
}

int main()
{
    int n,m;
    while(cin>>n>>m,n||m)
    {
        memset(flag,1,sizeof flag);
        memset(x,0,sizeof x);
        int p,x,y,v;
        while(m--)
        {
            scanf("%d%d%d%d",&p,&x,&y,&v);
            if(p>=1 && p<=3)update(x,y,p,v,1,1,n);
            else printf("%d\n",query(x,y,v,1,1,n));
        }
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值