蒟蒻初学ODT,求助
  • 板块P5350 序列
  • 楼主罗小菜
  • 当前回复2
  • 已保存回复2
  • 发布时间2022/5/14 10:44
  • 上次更新2023/10/28 01:30:08
查看原帖
蒟蒻初学ODT,求助
483252
罗小菜楼主2022/5/14 10:44

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;
}
2022/5/14 10:44
加载中...