zoukankan      html  css  js  c++  java
  • BZOJ 2962

    2962: 序列操作

    Time Limit: 50 Sec  Memory Limit: 256 MB
    Submit: 618  Solved: 225
    [Submit][Status][Discuss]

    Description

      有一个长度为n的序列,有三个操作1.I a b c表示将[a,b]这一段区间的元素集体增加c,2.R a b表示将[a,b]区间内所有元素变成相反数,3.Q a b c表示询问[a,b]这一段区间中选择c个数相乘的所有方案的和mod 19940417的值。

    Input

      第一行两个数n,q表示序列长度和操作个数。
      第二行n个非负整数,表示序列。
      接下来q行每行输入一个操作I a b c或者 R a b或者Q a b c意义如题目描述。

    Output

      对于每个询问,输出选出c个数相乘的所有方案的和mod19940417的值。

    Sample Input

    5 5
    1 2 3 4 5
    I 2 3 1
    Q 2 4 2
    R 1 5
    I 1 3 -1
    Q 1 5 1

    Sample Output

    40
    19940397
    样例说明
      做完第一个操作序列变为1 3 4 4 5。
      第一次询问结果为3*4+3*4+4*4=40。
      做完R操作变成-1 -3 -4 -4 -5。
      做完I操作变为-2 -4 -5 -4 -5。
      第二次询问结果为-2-4-5-4-5=-20。

    HINT

      100%的数据n<=50000,q<=50000,初始序列的元素的绝对值<=109,I a b c中保证[a,b]是一个合法区间,|c|<=109,R a b保证[a,b]是个合法的区间。Q a b c中保证[a,b]是个合法的区间1<=c<=min(b-a+1,20)。

    Source

     
    题解:
    线段树训练的好题(纯线段树维护的代码试炼),这题自己敲出来,就说明你的线段树方面的代码能力已经过关了。
     
    AC代码:
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define N 60050
    #define mod 19940417LL
    #define ll long long
    #define lc k<<1
    #define rc k<<1|1
    #define mid (l+r>>1)
    using namespace std;
    struct use{
        ll fi[21],delta,rev;
        void init(){memset(fi,0,sizeof(fi));delta=rev=0;}
    }tr[N<<2];
    ll ai[N],cc[N][21],mi[N];
    inline char letter(){
        for(register char ch=getchar();;ch=getchar()) if(ch>='A'&&ch<='Z') return ch;
    }
    inline ll read(){
        register ll x=0,f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    use updata(use x,use y){
        use ci;ci.init();
        for(int i=1;i<=20;i++){
            ci.fi[i]=(x.fi[i]+y.fi[i])%mod;
            for(int j=1;j<i;j++)
                ci.fi[i]=(ci.fi[i]+x.fi[j]*y.fi[i-j]%mod)%mod;
        }
        return ci;
    }
    void build(int k,int l,int r){
        if(l==r){
            tr[k].fi[1]=ai[l];
            return ;
        }
        build(lc,l,mid);build(rc,mid+1,r);
        tr[k]=updata(tr[lc],tr[rc]);
    }
    void paint(int k,int l,int r,ll x){
        ll xx;
        if(!x){
            tr[k].rev^=1;
            tr[k].delta=((mod-tr[k].delta)%mod+mod)%mod;
            for(int j=1;j<=min(r-l+1,20);j+=2) tr[k].fi[j]=((mod-tr[k].fi[j])%mod+mod)%mod;
        }
        else{
            x=(x%mod+mod)%mod;
            tr[k].delta=((tr[k].delta+x)%mod+mod)%mod;
            for(int q,j=min(r-l+1,20);j;j--){
                for(xx=x,q=j-1;q;q--){
                    tr[k].fi[j]=(tr[k].fi[j]+cc[r-l+1-q][j-q]*xx%mod*tr[k].fi[q]%mod)%mod;
                    xx=x*xx%mod;
                }
                tr[k].fi[j]=(tr[k].fi[j]+cc[r-l+1][j]*xx%mod)%mod;  
            }
         
        }
    }
    void pushdown(int k,int l,int r){
        if(tr[k].rev) paint(lc,l,mid,0),paint(rc,mid+1,r,0);
        if(tr[k].delta) paint(lc,l,mid,tr[k].delta),paint(rc,mid+1,r,tr[k].delta);
        tr[k].rev=tr[k].delta=0;
    }
    void ins(int k,int l,int r,int x,int y,int v){
        if(x<=l&&r<=y){
            paint(k,l,r,v);
            return ;
        }
        pushdown(k,l,r);
        if(x<=mid) ins(lc,l,mid,x,y,v);
        if(y>mid) ins(rc,mid+1,r,x,y,v);
        tr[k]=updata(tr[lc],tr[rc]);
    }
    void rev(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y){
            paint(k,l,r,0);
            return ;
        }
        pushdown(k,l,r);
        if(x<=mid) rev(lc,l,mid,x,y);
        if(y>mid) rev(rc,mid+1,r,x,y);
        tr[k]=updata(tr[lc],tr[rc]);
    }
    use query(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y) return tr[k];
        pushdown(k,l,r);
        use x1,x2;x1.init();x2.init();
        bool f1(0),f2(0);
        if(x<=mid) x1=query(lc,l,mid,x,y),f1=1;
        if(y>mid) x2=query(rc,mid+1,r,x,y),f2=1;
        if(f1&&f2) return updata(x1,x2);
        return f1?x1:x2;
    }
    int main(){
        ll n,q,a,b,c;char ch;
        n=read();q=read();
        for(int i=0;i<=n;i++) cc[i][0]=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=20;j++){
                cc[i][j]=(cc[i-1][j-1]+cc[i-1][j])%mod;
            }
        }
        for(int i=1;i<=n;i++){
            ai[i]=read();ai[i]=(ai[i]%mod+mod)%mod;
        }
        build(1,1,n);
        for(int i=1;i<=q;i++){
            if((ch=letter())=='I'){
                a=read();b=read();c=read();
                c=(c%mod+mod)%mod;
                if(!c) continue;
                ins(1,1,n,a,b,c);
            }
            else if(ch=='R'){
                a=read();b=read();
                rev(1,1,n,a,b);
            }
            else{
                a=read();b=read();c=read();
                use ci=query(1,1,n,a,b);
                printf("%lld
    ",ci.fi[c]);
            }
        }
        return 0;
    }
  • 相关阅读:
    使用 Spring data redis 结合 Spring cache 缓存数据配置
    Spring Web Flow 笔记
    Linux 定时实行一次任务命令
    css js 优化工具
    arch Failed to load module "intel"
    go 冒泡排序
    go (break goto continue)
    VirtualBox,Kernel driver not installed (rc=-1908)
    go运算符
    go iota
  • 原文地址:https://www.cnblogs.com/shenben/p/5727042.html
Copyright © 2011-2022 走看看