zoukankan      html  css  js  c++  java
  • 洛谷 P3373 【模板】线段树 2

    在基础线段树的模板上做了优化,具体看eval函数和push_down.

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
    
    int n,m,p;
    int a[N];
    int l,r,d;
    
    struct Node{
    	int l,r;
    	int sum,add,mul;
    }tr[N<<2];
    
    void push_up(int u){
    	tr[u].sum=(tr[u<<1].sum+tr[u<<1|1].sum)%p;
    }
    
    void eval(Node &root,ll add,ll mul){
    	root.sum=((ll)root.sum*mul+(ll)(root.r-root.l+1)*add)%p;
    	root.mul=((ll)root.mul*mul)%p;
    	root.add=((ll)root.add*mul+add)%p;
    }
    
    void push_down(int u){
    	eval(tr[u<<1],tr[u].add,tr[u].mul);
    	eval(tr[u<<1|1],tr[u].add,tr[u].mul);
    	tr[u].add=0;
    	tr[u].mul=1;
    }
    
    void build(int u,int l,int r){
    	if(l==r) tr[u]={l,r,a[r],0,1};
    	else{
    		tr[u]={l,r,0,0,1};
    		int mid=(l+r)>>1;
    		build(u<<1,l,mid);
    		build(u<<1|1,mid+1,r);
    		push_up(u);
    	}
    }
    
    void modify(int u,int l,int r,ll add,ll mul){
    	if(tr[u].l>=l && tr[u].r<=r) eval(tr[u],add,mul);
    	else{
    		push_down(u);
    		int mid=(tr[u].l+tr[u].r)>>1;
    		if(l<=mid) modify(u<<1,l,r,add,mul);
    		if(r>mid) modify(u<<1|1,l,r,add,mul);
    		push_up(u);
    	}
    }
    
    ll query(int u,int l,int r){
    	if(tr[u].l>=l && tr[u].r<=r) return tr[u].sum;
    	
    	push_down(u);
    
    	int mid=(tr[u].l+tr[u].r)>>1;
    	
    	ll sum=0;
    
    	if(l<=mid) sum=query(u<<1,l,r);
    	if(r>mid) sum=(sum+query(u<<1|1,l,r))%p;
    	return sum;
    }
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    
    	cin>>n>>m>>p;
    
    	rep(i,1,n) cin>>a[i];
    
    	build(1,1,n);
    
    	while(m--){
    		int op;
    		cin>>op;
    		if(op==1){
    			cin>>l>>r>>d;
    			modify(1,l,r,0,d);
    		}
    		else if(op==2){
    			cin>>l>>r>>d;
    			modify(1,l,r,d,1);
    		}
    		else{
    			cin>>l>>r;
    			cout<<query(1,l,r)<<'
    ';
    		}
    	}
    
    
        return 0;
    }
    
  • 相关阅读:
    CSS3背景
    CSS3嵌入字体
    CSS3控制单行文本的溢出
    CSS3渐变色彩
    CSS3图片边框
    CSS中的各类选择器
    HTML 5入门知识——Drag
    今天是星期五,昨天下午回来之前,公司的人员都等施佳回来开会讨论需求
    这些天晚上有点睡不好,也是关于一个事情
    昨天回来后11点的时候吧午饭弄了
  • 原文地址:https://www.cnblogs.com/lr599909928/p/14097570.html
Copyright © 2011-2022 走看看