zoukankan      html  css  js  c++  java
  • BZOJ1798 [Ahoi2009]Seq 维护序列seq

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

    题目链接:BZOJ1798

    正解:线段树

    解题报告:

      考虑在线段树上维护一个乘法和加法标记,为了方便,我们把两个标记变成一个式子:$cx+d$的形式。

      对于一次加法操作,我们的二元组相当于是$(1,add*len)$,而乘法操作则是$(c,0)$,这个标记可以直接合并,下传的时候合并一下就好了。

    //It is made by ljh2000
    //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <ctime>
    #define lc root<<1
    #define rc root<<1|1
    #define rep(i,j,k) for(int i=j;i<=k;i++)
    #define reg(i,x) for(int i=first[x];i;i=next[i])
    using namespace std;
    typedef long long LL;
    const int MAXN = 300011;
    int n,m,p;
    struct node{ int l,r; LL len,c,d,sum; }a[MAXN*3];
    inline void update(int root){ a[root].sum=(a[lc].sum+a[rc].sum)%p; }
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void build(int root,int l,int r){
    	a[root].l=l; a[root].r=r; a[root].len=r-l+1; a[root].c=1; a[root].d=0;
    	if(l==r) { a[root].sum=getint(); return ; }
    	int mid=(l+r)>>1; build(lc,l,mid); build(rc,mid+1,r);
    	a[root].sum=a[lc].sum+a[rc].sum; a[root].sum%=p;//!!!
    }
    
    inline void calc(node &q,LL c,LL d){
    	q.c=q.c*c%p;
    	q.d=(q.d*c%p+d)%p;
    	q.sum=(c/*!!!*/*q.sum%p+d/*!!!*/*q.len%p/*!!!*/)%p;
    	if(q.l==q.r) q.c=1,q.d=0;
    }
    
    inline void pushdown(int root,int l,int r){
    	if(l==r) { a[root].c=1; a[root].d=0; return ; }
    	if(a[root].c==1 && a[root].d==0) return ;
    	calc(a[lc],a[root].c,a[root].d);
    	calc(a[rc],a[root].c,a[root].d);
    	a[root].c=1; a[root].d=0;
    }
    
    inline void modify(int root,int l,int r,int ql,int qr,LL c,LL d){
    	pushdown(root,l,r);
    	if(ql<=l && r<=qr) { calc(a[root],c,d); return ; }
    	int mid=(l+r)>>1;
    	if(ql<=mid) modify(lc,l,mid,ql,qr,c,d);
    	if(qr>mid) modify(rc,mid+1,r,ql,qr,c,d);
    	update(root);
    }
    
    inline LL query(int root,int l,int r,int ql,int qr){
    	pushdown(root,l,r);
    	if(ql<=l && r<=qr) return a[root].sum;
    	int mid=(l+r)>>1;
    	if(ql>mid) return query(rc,mid+1,r,ql,qr); 
    	else if(qr<=mid) return query(lc,l,mid,ql,qr);
    	else return ( query(lc,l,mid,ql,qr)+query(rc,mid+1,r,ql,qr) )%p;
    	update(root);
    }
    
    inline void work(){
    	n=getint(); p=getint(); build(1,1,n);
    	m=getint(); int type,l,r; LL cc;
    	while(m--) {
    		type=getint(); l=getint(); r=getint();
    		if(type==1) { cc=getint(); cc%=p; modify(1,1,n,l,r,cc,0); }
    		else if(type==2) { cc=getint(); cc%=p;modify(1,1,n,l,r,1,cc); }
    		else printf("%lld
    ",query(1,1,n,l,r));
    	}
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("1798.in","r",stdin);
    	freopen("1798.out","w",stdout);
    #endif
        work();
        return 0;
    }
    //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    

      

  • 相关阅读:
    SQL SERVER 2005分区表切换
    对SQL SERVER2005中表和索引存储结构的一些理解
    SQL SERVER 2005 DBCC IND命令说明
    面向对象的基本原则
    SQL SERVER 2005 DBCC PAGE命令说明
    Mac 使用ab性能测试工具
    Struts2初始化过程代码分析
    maven开发过程实践之二(配置项与源代码分离 processresources)
    简单之美
    Maven开发过程实践之三—(单元测试报告 test)
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6687705.html
Copyright © 2011-2022 走看看