RT
代码:
#include<cstdio>
#include<iostream>
#include<set>
using namespace std;
#define int long long
const int MAXN=1e6;
const int MOD=1e9+7;
struct node
{
int l,r;
mutable int val;
inline bool operator < (const node &temp) const
{
return l<temp.l;
}
}A[MAXN],B[MAXN];
set<node> tree;
int n,m;
int lst,lstl=1;
inline auto split(int pos)
{
auto it=tree.lower_bound({pos,0,0});
if(it!=tree.end() && it->l==pos) return it;
it--;
int l=it->l,r=it->r,val=it->val;
tree.erase(it);
tree.insert({l,pos-1,val});
return tree.insert({pos,r,val}).first;
}
inline int query(int l,int r)
{
auto end=split(r+1),begin=split(l);
int ans=0;
for(;begin!=end;begin++) ans=(ans+begin->val*(begin->r-begin->l+1)%MOD)%MOD;
return ans;
}
inline void assign(int l,int r,int v)
{
auto end=split(r+1),begin=split(l);
tree.erase(begin,end);
tree.insert({l,r,v});
return ;
}
inline void update_add(int l,int r,int v)
{
auto end=split(r+1),begin=split(l);
for(;begin!=end;begin++) begin->val=(begin->val+v)%MOD;
return ;
}
inline void Copy(int l1,int r1,int l2,int r2)
{
int cnt=0;
auto end=split(r1+1),begin=split(l1);
for(;begin!=end;begin++)
{
A[++cnt].l=begin->l;
A[cnt].r=begin->r;
A[cnt].val=begin->val;
}
end=split(r2+1),begin=split(l2);
tree.erase(begin,end);
for(int i=1;i<=cnt;i++) tree.insert({l2+A[i].l-l1,l2+A[i].r-l1,A[i].val});
return ;
}
inline void Swap(int l1,int r1,int l2,int r2)
{
int cnt1=0,cnt2=0;
auto end1=split(r1+1),begin1=split(l1);
for(auto it=begin1;it!=end1;it++)
{
A[++cnt1].l=it->l;
A[cnt1].r=it->r;
A[cnt1].val=it->val;
}
tree.erase(begin1,end1);
auto end2=split(r2+1),begin2=split(l2);
for(auto it=begin2;it!=end2;it++)
{
B[++cnt2].l=it->l;
B[cnt2].r=it->r;
B[cnt2].val=it->val;
}
tree.erase(begin2,end2);
for(int i=1;i<=cnt2;i++) tree.insert({l1+B[i].l-l2,l1+B[i].r-l2,B[i].val});
for(int i=1;i<=cnt1;i++) tree.insert({l2+A[i].l-l1,l2+A[i].r-l1,A[i].val});
return ;
}
inline void Reverse(int l,int r)
{
int cnt=0;
auto end=split(r+1),begin=split(l);
for(auto it=begin;it!=end;it++)
{
A[++cnt].l=it->l;
A[cnt].r=it->r;
A[cnt].val=it->val;
}
tree.erase(begin,end);
for(int i=1;i<=cnt;i++) tree.insert({r-A[i].r+l,r-A[i].l+l,A[i].val});
return ;
}
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
cin>>n>>m>>lst;
for(int i=2;i<=n;i++)
{
int x;
cin>>x;
if(x!=lst)
{
tree.insert({lstl,i-1,lst});
lst=x;
lstl=i;
}
}
tree.insert({lstl,n,lst});
for(int i=1;i<=m;i++)
{
int op;
cin>>op;
if(op==1)
{
int l,r;
cin>>l>>r;
cout<<query(l,r)<<"\n";
}
if(op==2)
{
int l,r,v;
cin>>l>>r>>v;
assign(l,r,v%MOD);
}
if(op==3)
{
int l,r,v;
cin>>l>>r>>v;
update_add(l,r,v%MOD);
}
if(op==4)
{
int l1,l2,r1,r2;
cin>>l1>>r1>>l2>>r2;
Copy(l1,r1,l2,r2);
}
if(op==5)
{
int l1,l2,r1,r2;
cin>>l1>>r1>>l2>>r2;
Swap(l1,r1,l2,r2);
}
if(op==6)
{
int l,r;
cin>>l>>r;
Reverse(l,r);
}
}
for(auto it=tree.begin();it!=tree.end();it++) for(int i=it->l;i<=it->r;i++) cout<<it->val<<" ";
return 0;
}