自学内容网 自学内容网

【数据结构】动态开点线段树

 

 

动态开点线段树 | henrytb's blog (henrytbtrue.github.io) 

算法学习笔记(49): 线段树的拓展 - 知乎 (zhihu.com)

星际旅行 终于拿到80pts啦

计算机软件能力认证考试系统

#include<iostream>
using namespace std;
#define ll long long
const ll N=100010;
const ll mod=1e9+7;
#define ll long long

struct Tree{
ll ls,rs;
ll len;
ll s[3];
ll k;ll mul[3];ll add[3];
}tr[4*3*N];ll idx=0;





void rotatee(ll a[]){
ll temp=a[0];
a[0]=a[1];a[1]=a[2];a[2]=temp;

}

void eval(Tree& u,ll k){
k%=3;for(ll i=1;i<=k;i++){
rotatee(u.s);rotatee(u.mul);rotatee(u.add);
}
u.k=(u.k+k)%3;
}
void eval(Tree& u,ll a[],ll b[]){
for(ll i=0;i<3;i++){
    u.s[i]=(u.s[i]*a[i]%mod+b[i]*u.len%mod)%mod;
    u.mul[i]=(u.mul[i]*a[i])%mod;
    u.add[i]=(u.add[i]*a[i]%mod+b[i])%mod;
}

}




void pushup(Tree& u,Tree& l,Tree& r){
for(ll i=0;i<3;i++)u.s[i]=(l.s[i]+r.s[i])%mod;

}void pushup(ll u){
pushup(tr[u],tr[tr[u].ls],tr[tr[u].rs]);
}

void pushdown(Tree& u,Tree& l,Tree& r){
eval(l,u.k);eval(r,u.k);
eval(l,u.mul,u.add);eval(r,u.mul,u.add);
u.k=0;for(ll i=0;i<3;i++)u.mul[i]=1,u.add[i]=0;
}
void pushdown(ll u){pushdown(tr[u],tr[tr[u].ls],tr[tr[u].rs]);
}






ll add(ll l,ll r){
ll u=++idx;
tr[u].ls=tr[u].rs=0;
tr[u].len=r-l+1;
tr[u].s[0]=tr[u].s[1]=tr[u].s[2]=0;
tr[u].k=0;for(ll i=0;i<3;i++)tr[u].mul[i]=1,tr[u].add[i]=0;
return u;
}


void modify(ll& u,ll l,ll r,ll x,ll y,ll k,ll a[],ll b[]){
if(!u)u=add(l,r);
if(x<=l&&r<=y){
    eval(tr[u],k);
    eval(tr[u],a,b);
    return ;
}

ll mid=(l+r)>>1;
if(!tr[u].ls)tr[u].ls=add(l,mid);
if(!tr[u].rs)tr[u].rs=add(mid+1,r);
pushdown(u);
if(x<=mid)modify(tr[u].ls,l,mid,x,y,k,a,b);
if(y>=mid+1)modify(tr[u].rs,mid+1,r,x,y,k,a,b);
pushup(u);
}

Tree query(ll& u,ll l,ll r,ll x,ll y){
if(!u)u=add(l,r);
if(x<=l&&r<=y){
    return tr[u];
}

ll mid=(l+r)>>1;
if(!tr[u].ls)tr[u].ls=add(l,mid);
if(!tr[u].rs)tr[u].rs=add(mid+1,r);
pushdown(u);
if(y<=mid)return query(tr[u].ls,l,mid,x,y);
else if(x>=mid+1)return query(tr[u].rs,mid+1,r,x,y);
else {
    Tree leftt=query(tr[u].ls,l,mid,x,y);
    Tree rightt=query(tr[u].rs,mid+1,r,x,y);
    Tree root;
    pushup(root,leftt,rightt);
    return root;
}

}



ll get_ans(ll s[]){
    ll res=0;
for(ll i=0;i<3;i++){
    res=(res+s[i]*s[i]%mod)%mod;
}
return res;
}
int  main(){
    ll n,m;
cin>>n>>m;

ll root=0;
ll L=1;ll R=n+10;
while(m--){
        ll op;ll x,y;cin>>op>>x>>y;
        ll a[3]={1,1,1};ll b[3]={0,0,0};
if(op==1){
    cin>>b[0]>>b[1]>>b[2];
    modify(root,L,R,x,y,0,a,b);
}
else if(op==2){
    cin>>a[0];a[1]=a[2]=a[0];
    modify(root,L,R,x,y,0,a,b);
}
else if(op==3){
    modify(root,L,R,x,y,1,a,b);
}
else {
    cout<<get_ans(query(root,L,R,x,y).s)%mod<<endl;
}
}

}


原文地址:https://blog.csdn.net/2302_80811345/article/details/142366666

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!