• bzoj1798[Ahoi2009]Seq 维护序列seq


    Description

    老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

    Input

    第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (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

    HINT

    【样例说明】

    初始时数列为(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。



    测试数据规模如下表所示

    数据编号 1 2 3 4 5 6 7 8 9 10
    N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
    M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

    就是个线段树……支持区间加、区间乘、区间求和

    但是写标记下传的时候加和乘运算优先级没分清楚,然后一直wa

    #include<cstdio>
    #define maxn 1000000
    struct treenode{
    	int l,r,ls,rs;
    	long long tot,add,mult;
    }tree[maxn];
    inline int read()
    {
        int x=0,f=1;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;
    }
    int n,m,p,treesize;
    int a[200001];
    inline void update(int k)
    {tree[k].tot=(tree[tree[k].ls].tot+tree[tree[k].rs].tot)%p;}
    void downput(int k)
    {
        int t=tree[k].r-tree[k].l+1;
        if(t==1)return;
        long long m=tree[k].mult,a=tree[k].add;tree[k].mult=1;tree[k].add=0;
        tree[tree[k].ls].tot=(tree[tree[k].ls].tot*m+(t-(t>>1))*a)%p;
        tree[tree[k].rs].tot=(tree[tree[k].rs].tot*m+(t>>1)*a)%p;
        tree[tree[k].ls].add=(tree[tree[k].ls].add*m+a)%p;
        tree[tree[k].rs].add=(tree[tree[k].rs].add*m+a)%p;
        tree[tree[k].ls].mult=tree[tree[k].ls].mult*m%p;
        tree[tree[k].rs].mult=tree[tree[k].rs].mult*m%p;
    }
    inline void buildtree(int l,int r)
    {
    	if (l>r) return;
    	int now=++treesize;
    	tree[now].l=l;
    	tree[now].r=r;
    	tree[now].mult=1;
    	if (l==r)
    	{
    		tree[now].tot=a[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	tree[now].ls=treesize+1;
    	buildtree(l,mid);
    	tree[now].rs=treesize+1;
    	buildtree(mid+1,r);
    	update(now);
    }
    inline void work(int k,int l,int r,long long m,long long a)
    {
    	downput(k);
    	int x=tree[k].l,y=tree[k].r;
    	if (l==x&&r==y)
    	{
    		long long len=y-x+1;
    		tree[k].mult=(tree[k].mult*m)%p;
    		tree[k].add=(tree[k].add*m+a)%p;
    		tree[k].tot=(tree[k].tot*m+a*len)%p;
    		return;
    	}
    	int mid=(x+y)>>1;
    	if (r<=mid) work(tree[k].ls,l,r,m,a);
    	else if (l>mid) work(tree[k].rs,l,r,m,a);
    	else 
    	{
    		work(tree[k].ls,l,mid,m,a);
    		work(tree[k].rs,mid+1,r,m,a);
    	}
    	update(k);
    }
    inline long long ask(int k,int l,int r)
    {
    	downput(k);
    	int x=tree[k].l,y=tree[k].r;
    	if (l==x&&r==y) return tree[k].tot;
    	int mid=(x+y)>>1;
    	long long ans;
    	if (r<=mid) ans=ask(tree[k].ls,l,r);
    	else if (l>mid) ans=ask(tree[k].rs,l,r);
    	else ans=ask(tree[k].ls,l,mid)+ask(tree[k].rs,mid+1,r);
    	update(k);
    	return ans%p;
    }
    int main()
    {
    	n=read();p=read();
    	for (int i=1;i<=n;i++)a[i]=read();
    	buildtree(1,n);
    	m=read();
    	while (m--)
    	{
    		int opr=read(),x,y,z;
    		if(opr==1)
    		{
    			x=read();y=read();z=read();
    			work(1,x,y,z,0);
    		}else
    		if (opr==2)
    		{
    			x=read();y=read();z=read();
    			work(1,x,y,1,z);
    		}
    		if (opr==3)
    		{
    			x=read(),y=read();
    			printf("%lld
    ",ask(1,x,y)%p);
    		}
    	}
    	return 0;
    }


    ——by zhber,转载请注明来源
  • 相关阅读:
    字典树+二叉树
    ##22
    简单代码优雅写
    全排列
    【持续更新】哟!又在写BUG啊!
    大整数加法和大整数乘法
    【框架编程思想】线数筛的高级应用(欧拉12题和欧拉21题)
    【持续更新】 用算法流程实现的代码块们
    记忆化
    资源收集
  • 原文地址:https://www.cnblogs.com/zhber/p/4035967.html
Copyright © 2020-2023  润新知