萌新初学ODT求调QwQ
  • 板块P5350 序列
  • 楼主Varphi
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/2/19 16:41
  • 上次更新2023/10/24 00:19:53
查看原帖
萌新初学ODT求调QwQ
838861
Varphi楼主2023/2/19 16:41
#include<bits/stdc++.h>
#define int long long
#define It set<odt>::iterator
using namespace std;
const int mod=1e9+7;
int n,m,op,l,r,x,y,tot,Tot;
struct odt{
	int l,r;
	mutable int val;
	bool operator <(const odt &n)const{
		return l<n.l;
	}
	odt(int a,int b,int c){
		l=a,r=b,val=c;
	}
	odt(int a){l=a;}
};
struct node{
	int len,x;
}cnt[300010],Cnt[300010];
set<odt>tree;
It split(int x){
	It it=tree.lower_bound(odt(x));
	if(it!=tree.end()&&it->l==x)return it;
	it--;
	int l=it->l,r=it->r,val=it->val;
	tree.erase(it);
	tree.insert(odt(l,x-1,val));
	return tree.insert(odt(x,r,val)).first;
}
void rvs(int l,int r,int x){
	It it2=split(r+1),it1=split(l);
	tree.erase(it1,it2);
	tree.insert(odt(l,r,x));
}
void add(int l,int r,int x){
	It it2=split(r+1),it1=split(l);
	for(It it=it1;it!=it2;it++)
		it->val=(it->val+x)%mod;
}
int Qry(int l,int r){
	It it2=split(r+1),it1=split(l);
	int ans=0;
	for(It it=it1;it!=it2;it++)
		ans=(it->val*(it->r-it->l+1)%mod+ans)%mod;
	return ans;
}
void cvr(int l,int r,int x,int y){
	It it2=split(r+1),it1=split(l);
	tot=0;
	for(It it=it1;it!=it2;it++)
		++tot,cnt[tot].len=it->r-it->l+1,cnt[tot].x=it->val;
	It it4=split(y+1),it3=split(x);
	tree.erase(it3,it4);
	for(int i=1,L=x;i<=tot;L+=cnt[i].len,i++)
		tree.insert(odt(L,L+cnt[i].len-1,cnt[i].x));
}
void swp(int l,int r,int x,int y){
	It it2=split(r+1),it1=split(l);
	tot=0;
	for(It it=it1;it!=it2;it++)
		++tot,cnt[tot].len=it->r-it->l+1,cnt[tot].x=it->val;
	tree.erase(it1,it2);
	It it4=split(y+1),it3=split(x);
	Tot=0;
	for(It it=it3;it!=it4;it++)
		++Tot,Cnt[Tot].len=it->r-it->l+1,Cnt[Tot].x=it->val;
	tree.erase(it3,it4);
	for(int i=1,L=x;i<=tot;L+=cnt[i].len,i++)
		tree.insert(odt(L,L+cnt[i].len-1,cnt[i].x));
	for(int i=1,L=l;i<=Tot;L+=Cnt[i].len,i++)
		tree.insert(odt(L,L+Cnt[i].len-1,Cnt[i].x));
}
void trn(int l,int r){
	It it2=split(r+1),it1=split(l);
	tot=0;
	for(It it=it1;it!=it2;it++)
		++tot,cnt[tot].len=it->r-it->l+1,cnt[tot].x=it->val;
	tree.erase(it1,it2);
	for(int i=tot,L=l;i>=1;L+=cnt[i].len,i--)
		tree.insert(odt(L,L+cnt[i].len-1,cnt[i].x));
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%lld",&l),tree.insert(odt(i,i,l));
	tree.insert(odt(n+1,n+1,-1));
	while(m--){
		scanf("%lld",&op);
		if(op==1){
			scanf("%lld%lld",&l,&r);
			printf("%lld\n",Qry(l,r));
		}
		if(op==2){
			scanf("%lld%lld%lld",&l,&r,&x);
			rvs(l,r,x);
		}
		if(op==3){
			scanf("%lld%lld%lld",&l,&r,&x);
			add(l,r,x);
		}
		if(op==4){
			scanf("%lld%lld%lld%lld",&l,&r,&x,&y);
			cvr(l,r,x,y);
		}
		if(op==5){
			scanf("%lld%lld%lld%lld",&l,&r,&x,&y);
			swp(l,r,x,y);
		}
		if(op==6){
			scanf("%lld%lld",&l,&r);
			trn(l,r);
		}
//		for(It it=tree.begin();it!=tree.end();it++)
//		for(int i=it->l;i<=it->r;i++)
//			if(it->val!=-1)
//			printf("%lld ",it->val);printf("\n");
	}
	for(It it=tree.begin();it!=tree.end();it++)
		for(int i=it->l;i<=it->r;i++)
			if(it->val!=-1)
			printf("%lld ",it->val);
	return 0;
}
2023/2/19 16:41
加载中...