寒假刷題27:洛谷P2023 [AHOI2009]維護序列 (線段樹)

題目鏈接:

P2023 [AHOI2009]維護序列

題目解析:

這題就離譜....寫着寫着感覺有點熟悉,再一看,這不就是之前P3373改一下輸入嗎?

AC代碼:


#include<iostream>
#include<cstdio>
#include<cstring>
#define  ll   long long
using namespace std;

struct Node
{
    long long l,r,mlz,plz,sum;
}tree[400010];
ll putnum[100010];
ll n,m,p;
void build(ll i,ll l,ll r)
{
    tree[i].l=l;tree[i].r=r;
    tree[i].plz=0;tree[i].mlz=1;
    if(l==r)
    {
        tree[i].sum=putnum[l]%p;
        return;
    }
    ll mid=(l+r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
}
void init()
{
    scanf("%lld%lld",&n,&p);
    for(ll i=1;i<=n;i++) scanf("%lld",&putnum[i]);
    scanf("%lld",&m);
    build(1,1,n);
}
void push_down(ll i)
{
   long long k1=tree[i].mlz,k2=tree[i].plz;
    tree[i<<1].sum=(tree[i<<1].sum*k1+k2*(tree[i<<1].r-tree[i<<1].l+1))%p;
    tree[i<<1|1].sum=(tree[i<<1|1].sum*k1+k2*(tree[i<<1|1].r-tree[i<<1|1].l+1))%p;
    tree[i<<1].mlz=(tree[i<<1].mlz*k1)%p;
    tree[i<<1|1].mlz=(tree[i<<1|1].mlz*k1)%p;
    tree[i<<1].plz=(tree[i<<1].plz*k1+k2)%p;
    tree[i<<1|1].plz=(tree[i<<1|1].plz*k1+k2)%p;
    tree[i].plz=0;
    tree[i].mlz=1;
    return ;

}
void mul(ll i,ll l,ll r,ll k)
{
    if(tree[i].r<=r && tree[i].l>=l)
    {
        tree[i].sum*=k;
        tree[i].sum%=p;
        tree[i].mlz*=k;
        tree[i].mlz%=p;
        tree[i].plz*=k;
        tree[i].plz%=p;
        return;
    }
    push_down(i);
    if(tree[i<<1].r>=l) mul(i<<1,l,r,k);
    if(tree[i<<1|1].l<=r) mul(i<<1|1,l,r,k);
    tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
}
void add(ll i,ll l,ll r,ll k)
{
    if(tree[i].r<=r && tree[i].l>=l)
    {
        tree[i].sum+=k*(tree[i].r-tree[i].l+1);
        tree[i].sum%=p;
        tree[i].plz+=k;
        tree[i].plz%=p;
        return;
    }
    push_down(i);
    if(tree[i<<1].r>=l) add(i<<1,l,r,k);
    if(tree[i<<1|1].l<=r) add(i<<1|1,l,r,k);
    tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
}
ll Search(ll i,ll l,ll r)
{
    if(tree[i].l>=l && tree[i].r<=r)
        return (tree[i].sum)%p;
    if(tree[i].r<l || tree[i].l>r)
        return 0;
    push_down(i);
    return (Search(i<<1,l,r)+Search(i<<1|1,l,r))%p;
}
int main()
{
    init();
    ll tag,x,y,k;
    for(ll i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&tag,&x,&y);
        if(tag==1)
        {
            scanf("%lld",&k);
            mul(1,x,y,k);
        }
        if(tag==2)
        {
            scanf("%lld",&k);
            add(1,x,y,k);
        }
        if(tag==3)
        {
            printf("%lld\n",Search(1,x,y));
        }
    }
    return 0;
}

 

發佈了60 篇原創文章 · 獲贊 23 · 訪問量 6600
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章