牛客题目线段树

主要是操作三,怎么计算

那么只需要维护区间和和区间平方和即可,1/2用逆元

多个标记注意标记之间有没有影响,mod其实很简单的,但是我标记没处理好一直wa,mod乱搞一下,我mod很丑

#include<iostream>
#include<algorithm>
#include<vector>
#define INF (1ll<<60)
using namespace std;
typedef long long ll;
const int N=1e5+9;
ll a[N];
ll n,m,mod;
struct node{
	ll val,pfval,mul,add;
}seg[N<<2];
ll tl(ll x){
	return x<<1;
}
ll tr(ll x){
	return x<<1|1;
}
ll qmi(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1){
            res=res*a%mod;
        }
        b>>=1;
        a=a*a%mod;
    }
    return res%mod;
}
ll inv(ll x){
    return qmi(x,mod-2)%mod;
}
void pushup(int id){
	seg[id].val=(seg[tl(id)].val%mod)+(seg[tr(id)].val%mod);
	seg[id].pfval=(seg[tl(id)].pfval%mod)+(seg[tr(id)].pfval%mod);
}
void build(int id,int l,int r){
	seg[id].mul=1;
    seg[id].add=0;
	if(l==r){
		seg[id].val=a[l]%mod;
		seg[id].pfval=a[l]*a[l]%mod;
	}else{
		int mid=(l+r)>>1;
		build(tl(id),l,mid);
		build(tr(id),mid+1,r);
		pushup(id);
	}
}
bool inrange(int L,int R,int l,int r){
	return L>=l && R<=r;
}
bool outofrange(int L,int R,int l,int r){
	return L>r || l>R;
}
void maketag(int id,int l,int r,ll v,int opt){
	if(opt==1){
        v%=mod;
		seg[id].val*=v;
        seg[id].val%=mod;
        seg[id].mul*=v;
        seg[id].mul%=mod;
        v=(v%mod)*v%mod;
		seg[id].pfval*=v;
        (seg[id].add*=v)%=mod;
        seg[id].pfval%=mod;
	}else{
        v%=mod;
		seg[id].pfval+=((v%mod)*v%mod)*(r-l+1)%mod+2*(v%mod)*(seg[id].val%mod);
        seg[id].pfval%=mod;
        seg[id].val+=(r-l+1)*(v%mod);  
        seg[id].val%=mod;
		seg[id].add+=v;
        seg[id].add%=mod;
	}
}
void pushdown(int id,int l,int r){
	int mid=(l+r)>>1;
    if(seg[id].mul!=1){
        maketag(tl(id),l,mid,seg[id].mul,1);
	    maketag(tr(id),mid+1,r,seg[id].mul,1);
    }
    if(seg[id].add){
        maketag(tl(id),l,mid,seg[id].add,2);
	    maketag(tr(id),mid+1,r,seg[id].add,2);
    }
	seg[id].mul=1;
	seg[id].add=0;
}
ll querysum(int id,int L,int R,int l,int r){
	if(inrange(L,R,l,r)){
		return seg[id].val%mod;
	}else if(!outofrange(L,R,l,r)){
		int mid=(L+R)>>1;
		pushdown(id,L,R);
		return querysum(tl(id),L,mid,l,r)%mod+querysum(tr(id),mid+1,R,l,r)%mod;
	}else{
		return 0;
	}
}
ll querypfsum(int id,int L,int R,int l,int r){
	if(inrange(L,R,l,r)){
		return seg[id].pfval%mod;
	}else if(!outofrange(L,R,l,r)){
		int mid=(L+R)>>1;
		pushdown(id,L,R);
		return querypfsum(tl(id),L,mid,l,r)%mod+querypfsum(tr(id),mid+1,R,l,r)%mod;
	}else{
		return 0;
	}
}
void modifymul(int id,int L,int R,int l,int r,ll v){
	if(inrange(L,R,l,r)){
		maketag(id,L,R,v,1);
	}else if(!outofrange(L,R,l,r)){
		int mid=(L+R)>>1;
		pushdown(id,L,R);
		modifymul(tl(id),L,mid,l,r,v);
		modifymul(tr(id),mid+1,R,l,r,v);
		pushup(id);
	}
}
void modifyadd(int id,int L,int R,int l,int r,ll v){
	if(inrange(L,R,l,r)){
		maketag(id,L,R,v,2);
	}else if(!outofrange(L,R,l,r)){
		int mid=(L+R)>>1;
		pushdown(id,L,R);
		modifyadd(tl(id),L,mid,l,r,v);
		modifyadd(tr(id),mid+1,R,l,r,v);
		pushup(id);
	}
}
void solve(){
    cin>>n>>m>>mod;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i]%=mod;
    }
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt;
        cin>>opt;
        if(opt==1){
            int l,r,v;
            cin>>l>>r>>v;
            modifyadd(1,1,n,l,r,v);
        }else if(opt==2){
            int l,r,v;
            cin>>l>>r>>v;
            modifymul(1,1,n,l,r,v);
        }else{
            int l,r;
            cin>>l>>r;
            ll res1=querysum(1,1,n,l,r)%mod;
            res1=res1*res1%mod;
            ll res2=querypfsum(1,1,n,l,r)%mod;
            res2%=mod;
            ll ans=(((res1-res2)%mod+mod)%mod)*inv(2)%mod;
            cout<<ans%mod<<'\n';
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

相关推荐

  1. 题目

    2024-06-11 15:36:01       29 阅读
  2. 挑战赛 B - 上博弈 -- 题解

    2024-06-11 15:36:01       71 阅读
  3. 网课:校门外的——题解

    2024-06-11 15:36:01       61 阅读
  4. 网课:机器翻译——题解

    2024-06-11 15:36:01       57 阅读
  5. 周赛 Round 51题解

    2024-06-11 15:36:01       23 阅读
  6. 洛谷 P3870 [TJOI2009] 开关 题解 线段

    2024-06-11 15:36:01       30 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-11 15:36:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-11 15:36:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-11 15:36:01       87 阅读
  4. Python语言-面向对象

    2024-06-11 15:36:01       96 阅读

热门阅读

  1. 【Anaconda】 anaconda常用命令总结

    2024-06-11 15:36:01       32 阅读
  2. 分治思想 +各种数据结构(线段树,归并排血)

    2024-06-11 15:36:01       26 阅读
  3. adb检测系统是否使用生产秘钥进行签名

    2024-06-11 15:36:01       34 阅读
  4. ptx学习

    2024-06-11 15:36:01       27 阅读
  5. Jmeter函数二次开发说明

    2024-06-11 15:36:01       30 阅读
  6. SpringMVC

    SpringMVC

    2024-06-11 15:36:01      29 阅读
  7. ls命令(Linux)

    2024-06-11 15:36:01       36 阅读
  8. 徐州服务器租用的费用如何?

    2024-06-11 15:36:01       32 阅读
  9. i18next国际化(react)

    2024-06-11 15:36:01       29 阅读
  10. qt+ffmpeg实现视频转码功能(亲测好用)

    2024-06-11 15:36:01       33 阅读
  11. TensorFlow 的基本概念和使用场景

    2024-06-11 15:36:01       29 阅读
  12. 一些科学方法的总结

    2024-06-11 15:36:01       26 阅读
  13. 【Dify系列文章——Redis介绍】

    2024-06-11 15:36:01       26 阅读