zoukankan      html  css  js  c++  java
  • [AHOI2009]维护序列

    题意

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

    (n,m leq 10^5)

    分析

    线段树模板题,努力打一下就好了。

    维护kx+b这种形式的标记是要注意:

    下放标记先乘再加,乘的时候要照顾加法标记,加的时候不用管乘法标记。

    代码

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #define rg register
    #define co const
    #define il inline
    #pragma GCC optimize ("O3")
    using namespace std;
    template<class T> il T read(rg T&x)
    {
        rg T data=0;
    	rg int w=1;
        rg char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int MAXN=1e5+7;
    int mod;
    
    struct node
    {
    	int sumv;
    	
    	il node(rg co int&s=0):sumv(s){}
    	
    	il node operator+(rg const node&rhs)const
    	{
    		return node((sumv + rhs.sumv) % mod);
    	}
    };
    
    int ql,qr,v;
    struct SegTree
    {
    	node data[MAXN<<2];
    	int addv[MAXN<<2],mulv[MAXN<<2];
    #define lson (now<<1)
    #define rson (now<<1|1)
    	il void build(rg int now,rg int l,rg int r)
    	{
    		addv[now]=0,mulv[now]=1;
    		if(l==r)
    		{
    			read(data[now].sumv);
    			return;
    		}
    		rg int mid=(l+r)>>1;
    		build(lson,l,mid);
    		build(rson,mid+1,r);
    		data[now]=data[lson]+data[rson];
    	}
    	
    	il void pushdown(rg int now,rg int l,rg int r)
    	{
    		if(mulv[now]!=1)
    		{
    			data[lson].sumv = (ll) data[lson].sumv * mulv[now] % mod,
    			addv[lson] = (ll) addv[lson] * mulv[now] % mod;
    			mulv[lson] = (ll) mulv[lson] * mulv[now] % mod;
    			data[rson].sumv = (ll) data[rson].sumv * mulv[now] % mod,
    			addv[rson] = (ll) addv[rson] * mulv[now] % mod;
    			mulv[rson] = (ll) mulv[rson] * mulv[now] % mod;
    			mulv[now] = 1;
    		}
    		if(addv[now])
    		{
    			rg int mid=(l+r)>>1;
    			(data[lson].sumv += (ll) (mid - l + 1) * addv[now] % mod ) %= mod,
    			(addv[lson] += addv[now]) %= mod;
    			(data[rson].sumv += (ll) (r - mid) * addv[now] % mod) %= mod,
    			(addv[rson] += addv[now]) %= mod;
    			addv[now]=0;
    		}
    	}
    	
    	il node query(rg int now,rg int l,rg int r)
    	{
    		if(ql<=l&&r<=qr)
    		{
    			return data[now];
    		}
    		pushdown(now,l,r);
    		rg int mid=(l+r)>>1;
    		if(qr<=mid)
    			return query(lson,l,mid);
    		if(ql>=mid+1)
    			return query(rson,mid+1,r);
    		return query(lson,l,mid)+query(rson,mid+1,r);
    	}
    	
    	il void mul(rg int now,rg int l,rg int r)
    	{
    		if(ql<=l&&r<=qr)
    		{
    			data[now].sumv = (ll)data[now].sumv * v % mod,
    			addv[now] = (ll)addv[now] * v % mod,
    			mulv[now] = (ll)mulv[now] * v % mod;
    			return;
    		}
    		pushdown(now,l,r);
    		rg int mid=(l+r)>>1;
    		if(ql<=mid)
    			mul(lson,l,mid);
    		if(qr>=mid+1)
    			mul(rson,mid+1,r);
    		data[now]=data[lson]+data[rson];
    	}
    	
    	il void add(rg int now,rg int l,rg int r)
    	{
    		if(ql<=l&&r<=qr)
    		{
    			(data[now].sumv += (ll)(r - l + 1) * v % mod) %= mod,
    			(addv[now] += v) %= mod;
    			return;
    		}
    		pushdown(now,l,r);
    		rg int mid=(l+r)>>1;
    		if(ql<=mid)
    			add(lson,l,mid);
    		if(qr>=mid+1)
    			add(rson,mid+1,r);
    		data[now]=data[lson]+data[rson];
    	}
    }T;
    
    int main()
    {
    //  freopen(".in","r",stdin);
    //  freopen(".out","w",stdout);
    	rg int n,m;
    	read(n);read(mod);
    	T.build(1,1,n);
    	read(m);
    	while(m--)
    	{
    		rg int opt;
    		read(opt);
    		if(opt==1) // mul
    		{
    			read(ql);read(qr);read(v);
    			T.mul(1,1,n);
    		}
    		else if(opt==2) // add
    		{
    			read(ql);read(qr);read(v);
    			T.add(1,1,n);
    		}
    		else if(opt==3)
    		{
    			read(ql);read(qr);
    			printf("%d
    ",T.query(1,1,n).sumv);
    		}
    	}
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    
    静渊以有谋,疏通而知事。
  • 相关阅读:
    小程序苹果手机上video会盖住绝对定位的view层,小程序 video 层级,原生组件
    两个高斯分布乘积的理论推导
    两个高斯分布的和的分布——正态分布的再生性
    随机变量、随机向量和随机有限集的定义
    UdpClient.BeginReceive(AsyncCallback, Object) 方法
    基于C#的UDP协议的异步实现
    基于C#实现串口通信Demo
    pitch、yaw、roll三个角的区别
    dotNET Core 3.X 使用 Jwt 实现接口认证
    C#使用RabbitMQ
  • 原文地址:https://www.cnblogs.com/autoint/p/9799952.html
Copyright © 2011-2022 走看看