zoukankan      html  css  js  c++  java
  • bzoj 5039: [Jsoi2014]序列维护

    Description

    JYY 有一个维护数列的任务。 他希望你能够来帮助他完成。
    JYY 现在有一个长度为 N 的序列 a1,a2,…,aN,有如下三种操作:
    1、 把数列中的一段数全部乘以一个值;
    2、 把数列中的一段数全部加上一个值;
    3、 询问序列中的一段数的和。
    由于答案可能很大,对于每个询问,你只需要告诉 JYY 这个询问的答案对 P
    取模的结果即可。

    Input

    第一行包含两个正整数, N 和 P;
    第二行包含 N 个非负整数,从左到右依次为 a1,a2,…,aN。
    第三行有一个整数 M,表示操作总数。
    接下来 M 行,每行满足如下三种形式之一:
    1、“ 1 t g c”(不含引号)。表示把所有满足 t ≤ i ≤ g 的 ai 全部乘以 c;
    2、“ 2 t g c”(不含引号)。表示把所有满足 t ≤ i ≤ g 的 ai 全部加上 c;
    3、“ 3 t g”(不含引号)。表示询问满足 t ≤ i ≤ g 的 ai 的和对 P 取模的值。
    1 ≤ N,M ≤ 10^5, 1 ≤ P, c, ai ≤ 2*10^9, 1 ≤ t ≤ g ≤ N

    Output

    对于每个以 3 开头的操作,依次输出一行,包含对应的结果。

    Sample Input

    7 43
    1 2 3 4 5 6 7
    5
    1 2 5 5
    3 2 4
    2 3 7 9
    3 1 3
    3 4 7

    Sample Output

    2
    35
    8
    【样例说明】
    初始时数列为(1,2,3,4,5,6,7)。
    经过第 1 次操作后,数列为(1,10,15,20,25,6,7)。
    对第 2 次操作,和为 10+15+20=45,模 43 的结果是 2。
    经过第 3 次操作后,数列为(1,10,24,29,34,15,16}
    对第 4 次操作,和为 1+10+24=35,模 43 的结果是 35。
    对第 5 次操作,和为 29+34+15+16=94,模 43 的结果是 8。
    ———————————————————————————————
    这道题先传乘法后传加法就行了
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    const int M=2e5+7;
    char buf[55*M],*ptr=buf-1;
    int read(){
        int ans=0,f=1,c=*++ptr;
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=*++ptr;}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=*++ptr;}
        return ans*f;
    }
    int n,m,P;
    int L,R;
    LL W;
    struct node{int l,r;LL v,h,tag;}tr[2*M];
    void up(int x){tr[x].v=(tr[x<<1].v+tr[x<<1^1].v)%P;}
    void calc_h(int x,LL w){
        tr[x].v=tr[x].v*w%P;
        tr[x].tag=tr[x].tag*w%P;
        tr[x].h=tr[x].h*w%P;
    }
    void calc_tag(int x,LL w){
        tr[x].v=(tr[x].v+(tr[x].r-tr[x].l+1)*w)%P;
        tr[x].tag=(tr[x].tag+w)%P;
    }
    void down(int x){
        if(tr[x].l==tr[x].r) return ;
        if(tr[x].h!=1){
            int ls=x<<1,rs=x<<1^1;
            calc_h(ls,tr[x].h);    calc_h(rs,tr[x].h);
            tr[x].h=1;
        }
        if(tr[x].tag){
            int ls=x<<1,rs=x<<1^1;
            calc_tag(ls,tr[x].tag);    calc_tag(rs,tr[x].tag);
            tr[x].tag=0;
        }
    }
    void build(int x,int l,int r){
        tr[x].l=l; tr[x].r=r;
        tr[x].h=1; tr[x].tag=0;
        if(l==r) return void(tr[x].v=read()%P);
        int mid=(l+r)>>1;
        build(x<<1,l,mid);
        build(x<<1^1,mid+1,r);
        up(x);
    }
    void modify_h(int x){
        if(L<=tr[x].l&&tr[x].r<=R) return void(calc_h(x,W));
        int mid=(tr[x].l+tr[x].r)>>1;
        down(x);
        if(L<=mid) modify_h(x<<1);
        if(R>mid) modify_h(x<<1^1);
        up(x);
    }
    void test(int x){
        if(tr[x].l==tr[x].r) return void(printf("[%d] ",tr[x].v));
        down(x);
        test(x<<1); test(x<<1^1);
    }
    void modify_tag(int x){
        if(L<=tr[x].l&&tr[x].r<=R) return void(calc_tag(x,W));
        int mid=(tr[x].l+tr[x].r)>>1;
        down(x);
        if(L<=mid) modify_tag(x<<1);
        if(R>mid) modify_tag(x<<1^1);
        up(x);
    }
    LL query(int x){
        if(L<=tr[x].l&&tr[x].r<=R) return tr[x].v;
        int mid=(tr[x].l+tr[x].r)>>1;
        down(x);
        LL ans=0;
        if(L<=mid) ans=(ans+query(x<<1))%P;
        if(R>mid) ans=(ans+query(x<<1^1))%P;
        return ans;
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin);
        n=read(); P=read();
        build(1,1,n);
        m=read();
        int k;
        for(int i=1;i<=m;i++){
            k=read();
            if(k==1) L=read(),R=read(),W=read(),modify_h(1);
            else if(k==2) L=read(),R=read(),W=read(),modify_tag(1);
            else L=read(),R=read(),printf("%lld
    ",query(1));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    鼠标移入和鼠标移出的提示,和样式的转换
    HTML5——新特性,拖放
    关于订阅发布模式
    titanium环境配置
    Matlab与C混编的介绍
    一个相对健壮的node 静态http服务器
    阻赛非阻塞同步异步
    最近在做的事以及一些安排
    说一说js中__proto__和prototype以及原型继承的那些事
    PHP写的爬虫,爬指定网站页面上的各种图片
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7512261.html
Copyright © 2011-2022 走看看