【BZOJ/Luogu】1798/P3373 [Ahoi2009]Seq 维护序列seq/【模板】线段树 2 区间加、乘线段树

20171014 大事件

题目交十次必定AC定理

RunID User Problem Result Memory Time Language Code_Length Submit_Time
2353336 FMM 1798 Accepted 10984 kb 5760 ms C++/Edit 3490 B 2017-10-14 10:43:56
2352043 FMM 1798 Wrong_Answer 10984 kb 964 ms C++/Edit 3469 B 2017-10-13 17:02:20
2352042 FMM 1798 Time_Limit_Exceed 10976 kb 30897 ms C++/Edit 3507 B 2017-10-13 17:01:52
2352015 FMM 1798 Wrong_Answer 10984 kb 908 ms C++/Edit 3478 B 2017-10-13 16:52:17
2350510 FMM 1798 Wrong_Answer 10984 kb 988 ms C++/Edit 3476 B 2017-10-12 21:42:46
2350312 FMM 1798 Wrong_Answer 10980 kb 852 ms C++/Edit 3211 B 2017-10-12 21:05:37
2350249 FMM 1798 Wrong_Answer 10980 kb 680 ms C++/Edit 3182 B 2017-10-12 20:54:23
2349881 FMM 1798 Runtime_Error 10976 kb 28 ms C++/Edit 3184 B 2017-10-12 19:50:49
2349875 FMM 1798 Runtime_Error 5900 kb 20 ms C++/Edit 2998 B 2017-10-12 19:49:05
2349688 FMM 1798 Runtime_Error 5896 kb 20 ms C++/Edit 2928 B 2017-10-12 18:54:52

祖国江山一片红


这个程序和区间加的线段树有点不同

区间加时不需要tag_down

而这里的区间加操作则需要下放标记


/**************************************************************
    Problem: 1798
    User: FMM
    Language: C++
    Result: Accepted
    Time:5760 ms
    Memory:10984 kb
****************************************************************/
 
#include 
#define C (c=getchar())
using namespace std;
 
struct wjnsb
{
    long long val,mult,plus;
}a[400005];
 
long long opt,m,n,INF,ori[100005];
 
inline void read(long long &n)
{
    long long f=1;char c;n=0;C;
    while (c<'0'||c>'9') c=='-'?f=-1,C:C;
    while (c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,C;
    return (void)(n*=f);
}
 
void bt(long long q,long long l,long long r)
{
    if (l==r)
    {
        a[q].mult=1;
        return (void)(a[q].val=ori[l]%INF);
    }
    a[q].mult=1;
    bt(q<<1,l,(l+r)>>1),bt((q<<1)+1,((l+r)>>1)+1,r);
    a[q].val=a[q<<1].val%INF+a[(q<<1)+1].val%INF;
    a[q].val%=INF;
    return;
}
 
void tag_down(long long x,long long l,long long r)
{
    int mid=(l+r)>>1;
    if (a[x].mult==1&&a[x].plus==0) return;
    if (l==r) return;
    a[x<<1].val=a[x<<1].val*a[x].mult%INF+(mid-l+1)*a[x].plus%INF;
    a[(x<<1)+1].val=a[(x<<1)+1].val*a[x].mult%INF+(r-mid)*a[x].plus%INF;
    a[x<<1].val%=INF;
    a[(x<<1)+1].val%=INF;
    a[x<<1].mult*=a[x].mult%INF;
    a[(x<<1)+1].mult*=a[x].mult%INF;
    a[x<<1].plus=a[x<<1].plus*a[x].mult%INF+a[x].plus%INF;
    a[(x<<1)+1].plus=a[(x<<1)+1].plus*a[x].mult%INF+a[x].plus%INF;
    a[x<<1].mult%=INF;
    a[(x<<1)+1].mult%=INF;
    a[x<<1].plus%=INF;
    a[(x<<1)+1].plus%=INF;
    a[x].mult=1;a[x].plus=0;
    return;
}
 
void reval(long long x){return (void)(a[x].val=(a[x<<1].val%INF+a[(x<<1)+1].val%INF)%INF);}
 
void mult(long long q,long long L,long long R,long long l,long long r,long long x)
{
    if (L==l&&R==r)
    {
        a[q].plus*=x;
        a[q].plus%=INF;
        a[q].val*=x;
        a[q].val%=INF;
        a[q].mult*=x;
        a[q].mult%=INF;
        return;
    }
    long long mid=(L+R)>>1;
    tag_down(q,L,R);
    if (r<=mid)
    {
        mult(q<<1,L,mid,l,r,x);
        reval(q);
    }
    else
    if (l>mid)
    {
        mult((q<<1)+1,mid+1,R,l,r,x);
        reval(q);
    }
    else
    {
        mult(q<<1,L,mid,l,mid,x);
        mult((q<<1)+1,mid+1,R,mid+1,r,x);
        reval(q);
    }
    return;
}
 
void plus(long long q,long long L,long long R,long long l,long long r,long long x)
{
    if (L==l&&R==r)
    {
        a[q].plus+=x;
        a[q].plus%=INF;
        a[q].val+=x*(r-l+1);
        a[q].val%=INF;
        return;
    }
    long long mid=(L+R)>>1;
    tag_down(q,L,R);
    a[q].val+=x*(r-l+1);
    a[q].val%=INF;
    if (r<=mid)
        plus(q<<1,L,mid,l,r,x);
    else
    if (l>mid)
        plus((q<<1)+1,mid+1,R,l,r,x);
    else
    {
        plus(q<<1,L,mid,l,mid,x);
        plus((q<<1)+1,mid+1,R,mid+1,r,x);
    }
    return;
}
 
long long query(long long q,long long L,long long R,long long l,long long r)
{
    if (L==l&&R==r) return a[q].val;
    long long mid=(L+R)>>1;
    tag_down(q,L,R);
    if (r<=mid)
    {
        return query(q<<1,L,mid,l,r)%INF;
    }
    else
    if (l>mid)
    {
        return query((q<<1)+1,mid+1,R,l,r)%INF;
    }
    else
    {
        return query(q<<1,L,mid,l,mid)%INF+query((q<<1)+1,mid+1,R,mid+1,r)%INF;
    }
}
 
int main(void)
{
    long long q,w,e;
    read(n),read(INF);
    for (register int i=1;i<=n;++i) read(ori[i]);
    bt(1,1,n);
    read(m);
    for (register int i=1;i<=m;++i)
    {
        read(opt),read(q),read(w);
        if (opt==1)
        {
            read(e);
            mult(1,1,n,q,w,e%INF);
        }
        else
        if (opt==2)
        {
            read(e);
            plus(1,1,n,q,w,e%INF);
        }
        else
        {
            printf("%lld\n",query(1,1,n,q,w)%INF);
        }
    }
    return 0;
}


你可能感兴趣的:(线段树,裸题练手感,Luogu,BZOJ)