题意:有一个序列(a_n)和若干操作:
- (mathrm{1 l r }) 求(a_l)到(a_r)的和
- (mathrm{2 l r val }) 将(a_l)到(a_r)赋值为(mathrm{val})
- (mathrm{3 l r val })将(a_l)到(a_r)加上(mathrm{val})
- (mathrm{4 l_1 r_1 l_2 r_2 })将(a_{l_1})到(a_{r_1})复制到(a_{l_2})到(a_{r_2})处
- (mathrm{5 l_1 r_1 l_2 r_2 })将(a_{l_1})到(a_{r_1})与(a_{l_2})到(a_{r_2})交换
- (mathrm{6 l r })将(a_l)到(a_r)翻转
分析:额,有区间赋值操作,那就上珂朵莉吧.操作一,二,三都是珂朵莉的常规操作,不讲了.
对于操作四,开一个vector,把([l1,r1])放进vector,然后把([l2,r2]erase)掉,再把(vector)里的(insert)到([l2,r2])中;
对于操作五,开两个(vector),像上面一样操作即可.
对于操作六,还是一个(vector),把([l,r])放进vector,然后把([l,r]erase)掉,再把(vector)里的(insert)到([r,l])中.注意是([r,l]).
因为STL常数较大,要吸氧才能光速逃跑...
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define IT set<node>::iterator
#define It vector<node>::iterator
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
const int mod=1e9+7;
struct node{
int l,r;mutable int val;
node(int L,int R=-1,int V=0){l=L,r=R,val=V;}
bool operator <(const node &x)const{
return l<x.l;
}
};
set<node>s;
inline IT split(int pos){
IT it=s.lower_bound(node(pos));
if(it!=s.end()&&it->l==pos)return it;
--it;int l=it->l,r=it->r,val=it->val;
s.erase(it);s.insert(node(l,pos-1,val));
return s.insert(node(pos,r,val)).first;
}
inline int ask_sum(int l,int r){
int val=0;IT itr=split(r+1),itl=split(l);
for(;itl!=itr;++itl)
val=(val+1ll*itl->val*(itl->r-itl->l+1)%mod)%mod;
return val;
}
inline void assign(int l,int r,int val){
IT itr=split(r+1),itl=split(l);
s.erase(itl,itr);s.insert(node(l,r,val));
}
inline void add(int l,int r,int val){
IT itr=split(r+1),itl=split(l);
for(;itl!=itr;++itl)itl->val=(itl->val+val)%mod;
}
inline void change1(int l1,int r1,int l2,int r2){
vector<node>q;q.clear();
for(IT itr=split(r1+1),itl=split(l1);itl!=itr;++itl)q.push_back(*itl);
IT itr=split(r2+1),itl=split(l2);s.erase(itl,itr);
for(It i=q.begin();i!=q.end();++i)s.insert(node(i->l-l1+l2,i->r-l1+l2,i->val));
}
inline void change2(int l1,int r1,int l2,int r2){
if(l1>l2)swap(l1,l2),swap(r1,r2);
vector<node>q1,q2;q1.clear(),q2.clear();
for(IT itr=split(r1+1),itl=split(l1);itl!=itr;++itl)q1.push_back(*itl);
for(IT itr=split(r2+1),itl=split(l2);itl!=itr;++itl)q2.push_back(*itl);
IT itr=split(r1+1),itl=split(l1);s.erase(itl,itr);
itr=split(r2+1),itl=split(l2);s.erase(itl,itr);
for(It i=q1.begin();i!=q1.end();++i)s.insert(node(i->l-l1+l2,i->r-l1+l2,i->val));
for(It i=q2.begin();i!=q2.end();++i)s.insert(node(i->l-l2+l1,i->r-l2+l1,i->val));
}
inline void Reverse(int l,int r){
vector<node>q;q.clear();
for(IT itr=split(r+1),itl=split(l);itl!=itr;++itl)q.push_back(*itl);
IT itr=split(r+1),itl=split(l);s.erase(itl,itr);
for(It i=q.begin();i!=q.end();++i)s.insert(node(r-i->r+l,r-i->l+l,i->val));
}
int main(){
int n=read(),m=read();
for(int i=1;i<=n;++i){
int a=read();
s.insert(node(i,i,a));
}
while(m--){
int opt=read(),l=read(),r=read();
if(opt==1){printf("%d
",ask_sum(l,r)%mod);continue;}
if(opt==2){int val=read();assign(l,r,val);continue;}
if(opt==3){int val=read();add(l,r,val);continue;}
if(opt==4){int l2=read(),r2=read();change1(l,r,l2,r2);continue;}
if(opt==5){int l2=read(),r2=read();change2(l,r,l2,r2);continue;}
if(opt==6){Reverse(l,r);continue;}
}
for(IT it=s.begin();it!=s.end();++it)
for(int i=it->l;i<=it->r;i++)
printf("%d ",it->val%mod);
printf("
");
return 0;
}