记录编号 553020 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [SYOI 2018] 简单的线段树 最终得分 100
用户昵称 Gravatarfw 是否通过 通过
代码语言 C++ 运行时间 12.501 s
提交时间 2020-08-10 16:41:22 内存使用 23.75 MiB
显示代码纯文本
#pragma GCC optimize (2)
#include <iostream>
#include <cstdio>
using namespace std;
namespace lsz {
    typedef long long ll;
    inline ll read () {
        ll s = 0;
        char ch = getchar ();
        while (ch < '0' || ch > '9') ch = getchar ();
        while (ch >= '0' && ch <= '9') s = (s << 3) + (s << 1) + ch - '0',ch = getchar ();
        return s;
    }
    inline int read1 () {
        int s = 0;
        char ch = getchar ();
        while (ch < '0' || ch > '9') ch = getchar ();
        while (ch >= '0' && ch <= '9') s = (s << 3) + (s << 1) + ch - '0',ch = getchar ();
        return s;
    }
    const int MAXN = 100001;
    int n,m;
    ll p;
    ll a[MAXN] = {0};
    struct Node {
    	ll l,r,sum,lz,mlz;
    	Node () {
    		l = r = sum = lz = 0;
    		mlz = 1;
    	}
    }tree[4*MAXN];
    void pushdown (ll i) {
    	 long long k1 = tree[i].mlz,k2 = tree[i].lz;
    		tree[i<<1].mlz  = (tree[i<<1].mlz   * k1)    %p;
    		tree[i<<1|1].mlz= (tree[i<<1|1].mlz * k1)    %p;
    		tree[i<<1].lz   = (k1      * tree[i<<1].lz   +     tree[i].lz)    %p;
    		tree[i<<1|1].lz = (k1      * tree[i<<1|1].lz +     tree[i].lz)    %p;
    		
    		tree[i<<1].sum  =  (tree[i<<1].sum   * k1      + (tree[i<<1].r   - tree[i<<1].l   + 1) * k2) %p;
    		tree[i<<1|1].sum=  (tree[i<<1|1].sum * k1      + (tree[i<<1|1].r - tree[i<<1|1].l + 1) * k2) %p;
    		tree[i].lz = 0;
    		tree[i].mlz = 1;	
    	return ;
    }
    void build(ll i,int l,int r) {
    	tree[i].l = l; tree[i].r = r;
    	if (l == r) {
    		tree[i].sum = a[l];
    		return ;
    	}
    	int mid = (l + r) >> 1;
    	build (i << 1,l,mid);
    	build (i << 1 | 1,mid + 1,r);
    	tree[i].sum = tree[i << 1].sum + tree[i << 1 | 1].sum;
    	return ;
    }
    ll search (ll i,int l,int r) {
    	if (tree[i].l >= l && tree[i].r <= r) {
    		return tree[i].sum % p;
    	}
    	
    	if (tree[i].l > r || tree[i].r < l) return 0;
    	pushdown (i);
    	ll s=0;
    	
    	if (tree[i << 1].r >= l) s += search(i << 1,l,r) % p;
    	if (tree[i << 1 | 1].l <= r) s += search(i << 1 | 1,l,r) % p;
    	return s % p;
    }
    void add (ll i,int l,int r,ll k) {
    	if (tree[i].l >= l && tree[i].r <= r) {
    		tree[i].sum = (tree[i].sum + k * (tree[i].r - tree[i].l + 1)) % p;
    		tree[i].lz = (tree[i].lz + k) % p;
    		return ;
    	}
    	if (tree[i].l > r || tree[i].r < l) return ;
    	pushdown (i);
    	if (tree[i << 1].r >= l) add(i << 1,l,r,k);
    	if (tree[i << 1 | 1].l <= r) add(i << 1 | 1,l,r,k);
    	tree[i].sum = (tree[i << 1].sum % p + tree[i << 1 | 1].sum % p) % p;
    	return ;
    }
    void mul (ll i,int l,int r,ll k) {
    	if (tree[i].l >= l && tree[i].r <= r) {
    		tree[i].sum = (tree[i].sum * k) % p;
    		tree[i].mlz = (tree[i].mlz * k) % p;
    		tree[i].lz = (tree[i].lz * k) % p;
    		return ;
    	}
    	if (tree[i].l > r || tree[i].r < l) return ;
    	pushdown (i);
    	if (tree[i << 1].r >= l) mul (i << 1,l,r,k);
    	if (tree[i << 1 | 1].l <= r) mul (i << 1 | 1,l,r,k); 
    	tree[i].sum = (tree[i << 1].sum % p + tree[i << 1 | 1].sum % p) % p;
    	return ;
    }
}
using namespace lsz;
int Main () {
	freopen("easilysegmenttree.in","r",stdin);
	freopen("easilysegmenttree.out","w",stdout);
	n = read1 ();
	m = read1 ();
	p = read ();
	build (1,1,n);
	int cm;
	int a,b,c;
	for (int q = 1;q <= m;++ q) {
		cm = read1 ();
		if (cm == 1) {
			a = read1 ();
			b = read1 ();
			c = read1 ();
			add (1,a,b,c);
		}
		if (cm == 2) {
			a = read1 ();
			b = read1 ();
			c = read1 ();
			mul (1,a,b,c);
		}
		if (cm == 3) {
			a = read1 ();
			b = read1 ();
			printf ("%lld\n",search (1,a,b) % p);
		}
	}
	return 0;
}
int ss = Main ();
int main () {;}