序列

洛咕

题意:有一个序列\(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\n",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("\n");
    return 0;
}

posted on 2019-08-14 15:22  PPXppx  阅读(163)  评论(0编辑  收藏  举报