提出 #39393644


ソースコード 拡げる

#ifndef LOCAL
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#endif

#include <bits/stdc++.h>
using namespace std;

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
template<class t,class u> bool chmin(t&a,u b){if(b<a){a=b;return true;}else return false;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

pi readpi(int off=0){
	int a,b;cin>>a>>b;
	return pi(a+off,b+off);
}

template<class t,class u>
void print(const pair<t,u>&p,int suc=1){
	print(p.a,2);
	print(p.b,suc);
}

template<class t,class u>
void print_offset(const pair<t,u>&p,ll off,int suc=1){
	print(p.a+off,2);
	print(p.b+off,suc);
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

template<class T>
void print_offset(const vector<T>&v,ll off,int suc=1){
	rep(i,v.size())
		print(v[i]+off,i==int(v.size())-1?suc:2);
}

template<class T,size_t N>
void print(const array<T,N>&v,int suc=1){
	rep(i,N)
		print(v[i],i==int(N)-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

void YES(bool ex=true){
	cout<<"YES\n";
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void NO(bool ex=true){
	cout<<"NO\n";
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void Yes(bool ex=true){
	cout<<"Yes\n";
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void No(bool ex=true){
	cout<<"No\n";
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
//#define CAPITAL
/*
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}*/
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int topbit(ull t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int botbit(ull a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
int popcount(ull t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
ll mask(int i){
	return (ll(1)<<i)-1;
}
ull umask(int i){
	return (ull(1)<<i)-1;
}
ll minp2(ll n){
	if(n<=1)return 1;
	else return ll(1)<<(topbit(n-1)+1);
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	//#ifdef LOCAL
	static mt19937_64 gen;
	/*#else
	static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
	#endif*/
	return uniform_int_distribution<ll>(l, r)(gen);
}

ll rand_int(ll k){ //[0,k)
	return rand_int(0,k-1);
}

template<class t>
void myshuffle(vc<t>&a){
	rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}
template<class t>
bool bis(const vc<t>&v,const t&a){
	return binary_search(all(v),a);
}

vvc<int> readGraph(int n,int m){
	vvc<int> g(n);
	rep(i,m){
		int a,b;
		cin>>a>>b;
		//sc.read(a,b);
		a--;b--;
		g[a].pb(b);
		g[b].pb(a);
	}
	return g;
}

vvc<int> readTree(int n){
	return readGraph(n,n-1);
}

vc<ll> presum(const vi&a){
	vc<ll> s(si(a)+1);
	rep(i,si(a))s[i+1]=s[i]+a[i];
	return s;
}
//BIT で数列を管理するときに使う (CF850C)
template<class t>
vc<t> predif(vc<t> a){
	gnr(i,1,si(a))a[i]-=a[i-1];
	return a;
}
template<class t>
vvc<ll> imos(const vvc<t>&a){
	int n=si(a),m=si(a[0]);
	vvc<ll> b(n+1,vc<ll>(m+1));
	rep(i,n)rep(j,m)
		b[i+1][j+1]=b[i+1][j]+b[i][j+1]-b[i][j]+a[i][j];
	return b;
}

//verify してないや
void transvvc(int&n,int&m){
	swap(n,m);
}
template<class t,class... Args>
void transvvc(int&n,int&m,vvc<t>&a,Args&...args){
	assert(si(a)==n);
	vvc<t> b(m,vi(n));
	rep(i,n){
		assert(si(a[i])==m);
		rep(j,m)b[j][i]=a[i][j];
	}
	a.swap(b);
	transvvc(n,m,args...);
}
//CF854E
void rotvvc(int&n,int&m){
	swap(n,m);
}
template<class t,class... Args>
void rotvvc(int&n,int&m,vvc<t>&a,Args&...args){
	assert(si(a)==n);
	vvc<t> b(m,vi(n));
	rep(i,n){
		assert(si(a[i])==m);
		rep(j,m)b[m-1-j][i]=a[i][j];
	}
	a.swap(b);
	rotvvc(n,m,args...);
}

//ソートして i 番目が idx[i]
//CF850C
template<class t>
vi sortidx(const vc<t>&a){
	int n=si(a);
	vi idx(n);iota(all(idx),0);
	sort(all(idx),[&](int i,int j){return a[i]<a[j];});
	return idx;
}
//vs[i]=a[idx[i]]
//例えば sortidx で得た idx を使えば単にソート列になって返ってくる
//CF850C
template<class t>
vc<t> a_idx(const vc<t>&a,const vi&idx){
	int n=si(a);
	assert(si(idx)==n);
	vc<t> vs(n);
	rep(i,n)vs[i]=a[idx[i]];
	return vs;
}
//CF850C
vi invperm(const vi&p){
	int n=si(p);
	vi q(n);
	rep(i,n)q[p[i]]=i;
	return q;
}

template<class t,class s=t>
s SUM(const vc<t>&a){
	return accumulate(all(a),s(0));
}

template<class t>
t MAX(const vc<t>&a){
	return *max_element(all(a));
}

template<class t>
t MIN(const vc<t>&a){
	return *min_element(all(a));
}

template<class t,class u>
pair<t,u> operator+(const pair<t,u>&a,const pair<t,u>&b){
	return mp(a.a+b.a,a.b+b.b);
}

vi vid(int n){
	vi res(n);iota(all(res),0);
	return res;
}

//copy-constructor,使えません
//find は lazy と組み合わせても動く (Petrozavodsk 2020w Day9 C)
//reverse は未知数
//erase,insert は動く
//split_cmp も動く
//max_right も動く

//AOJ DSL2G
template<class N>
struct splaytree{
	struct Node{
		using np=Node*;
		np l,r,p;
		bool rev;
		N x;
		Node():l(0),r(0),p(0),rev(false),x(){}
		void clear(){
			l=0;
			r=0;
			p=0;
			rev=0;
		}
		void reverse(){
			rev^=true;
			swap(l,r);
			x.reverse();
		}
		void push(){
			if(rev){
				if(l)l->reverse();
				if(r)r->reverse();
				rev=false;
			}
			if(l)x.pushl(l->x);
			if(r)x.pushr(r->x);
			x.clear();
		}
		np update(){
			x.single();
			if(l)x.updatel(l->x);
			if(r)x.updater(r->x);
			return this;
		}
		int pos(){
			if(p&&p->l==this)return -1;
			if(p&&p->r==this)return 1;
			return 0;
		}
		void prepare(){
			if(pos())
				p->prepare();
			push();
		}
		void rotate(){
			np q=p,c;
			if(pos()==1){
				c=l;
				l=p;
				p->r=c;
			}else{
				c=r;
				r=p;
				p->l=c;
			}
			if(c)c->p=p;
			p=p->p;
			q->p=this;
			if(p&&p->l==q)p->l=this;
			if(p&&p->r==q)p->r=this;
			q->update();
		}
		np splay(){
			prepare();
			while(pos()){
				int a=pos(),b=p->pos();
				if(b&&a==b)p->rotate();
				if(b&&a!=b)rotate();
				rotate();
			}
			return update();
		}
		/* deprecated
		template<class F,class...Args>
		np find(F f,Args&&...args){
			if(!(x.*f)(forward<Args>(args)...))return 0;
			push();
			x.single();
			np a=0;
			if(l)a=l->find(f,forward<Args>(args)...);
			if(a)return a;
			if((x.*f)(forward<Args>(args)...))return splay();
			return r->find(f,forward<Args>(args)...);
		}*/
		np left(){
			if(l)return l->left();
			else return splay();
		}
		np right(){
			if(r)return r->right();
			else return splay();
		}
		/*np root(){
			if(p)return p->root();
			else return this;
		}*/
		void chpar(np c){
			if(c){
				assert(!(c->p));
				c->p=this;
			}
		}
		np linkl(np c){
			assert(!l);
			chpar(l=c);
			return update();
		}
		np linkr(np c){
			assert(!r);
			chpar(r=c);
			return update();
		}
		np linklr(np c,np d){
			assert(!l&&!r);
			chpar(l=c);
			chpar(r=d);
			return update();
		}
		np cutl(){
			if(l){
				l->p=0;
				l=0;
			}
			return update();
		}
		np cutr(){
			if(r){
				r->p=0;
				r=0;
			}
			return update();
		}
		//XIX Opencup GP of Zhejiang A
		np get_next(){
			splay();
			if(!r)return 0;
			else return r->left();
		}
	};
	using np=Node*;
	np head;
	int alloc_total=0;
	splaytree(const splaytree&)=delete;
	void operator=(const splaytree&)=delete;
	splaytree():head(0){}
	~splaytree(){
		int del_total=0;
		while(head){
			del_total++;
			np nx=head->p;
			delete head;
			head=nx;
		}
		//assert(alloc_total==del_total);
	}
	//TL,MLが厳しいとき
	//FHC2022 Final E
	//もともと 118 秒くらいのコードが 98 秒になったが…
	/*splaytree(){
		const int S=20000000;
		np buf=new Node[S];
		buf[0].p=0;
		rng(i,1,S)buf[i].p=buf+(i-1);
		head=buf+(S-1);
	}
	~splaytree(){}*/
	np allocnode(){
		if(head){
			np res=head;
			head=res->p;
			return res;
		}else{
			alloc_total++;
			return new Node();
		}
	}
	//読んだ直後,x->p 以外の情報は生きている
	void freenode(np x){
		x->p=head;
		head=x;
	}
	/*vc<np> ps;
	unique_ptr<Node[]> buf;
	splaytree(int n):buf(new Node[n]),ps(n){
		rep(i,n)ps[i]=buf.get()+i;
	}
	//alloc/free 系書いてないわ
	*/
	//FHC2022 Final E/range_set/rect_set
	//assume no duplicate free
	void freetree(np x){
		if(!x)return;
		freetree(x->l);
		freetree(x->r);
		freenode(x);
		//ps.pb(x);
	}
	template<class...Args>
	np nn(Args&&...args){
		np a=allocnode();
		a->l=0;
		a->r=0;
		a->p=0;
		a->x=N(forward<Args>(args)...);
		return a;
	}
	np merge(np a,np b){
		if(!a)return b;
		if(!b)return a;
		return b->splay()->left()->linkl(a->splay());
	}
	//GCJ2022 Round2 D
	template<class...Args>
	np merge(np a,np b,Args...args){
		return merge(merge(a,b),args...);
	}
	template<bool C,class F,class...Args>
	pair<np,np> max_right_sub(np a,F f,Args&&...args){
		N cur;
		np x=0,y=0;
		while(a){
			a->push();
			N nx=a->x;nx.single();
			if(a->l)nx.updatel(a->l->x);
			nx.updatel(cur);
			if((nx.*f)(forward<Args>(args)...)){
				cur=nx;
				x=a;
				a=a->r;
			}else{
				y=a;
				a=a->l;
			}
		}
		if(x){
			x->splay();
			if constexpr(C)x->cutr();
		}
		if(y)y->splay();
		return mp(x,y);
	}
	//max_right で失敗する最初のノードを根にする
	//そのようなものがない場合は false が返ってくる
	template<class F,class...Args>
	bool max_right_splay(np&a,F f,Args&&...args){
		auto [x,y]=max_right_sub<false>(a,f,forward<Args>(args)...);
		if(y){
			a=y;
			return true;
		}else{
			a=x;
			return false;
		}
	}
	//分けた列の右端と左端が返ってくる
	//CF Dytechlab Cup 2022 G (lazy あり)
	template<class F,class...Args>
	pair<np,np> max_right_split(np a,F f,Args&&...args){
		return max_right_sub<true>(a,f,forward<Args>(args)...);
	}
	//XX Opencup GP of Wroclaw D
	//分けた列の右端と左端が返ってくる
	//CF740 D (lazy あり)
	//CF Dytechlab Cup 2022 G (lazy あり)
	template<bool C,class F,class T>
	pair<np,np> split_sub(np a,F cmp,T v){
		np x=0,y=0;
		while(a){
			a->push();
			if(cmp(a->x,v)){
				x=a;
				a=a->r;
			}else{
				y=a;
				a=a->l;
			}
		}
		if(x){
			x->splay();
			if constexpr(C)x->cutr();
		}
		if(y)y->splay();
		return mp(x,y);
	}
	template<class F,class T>
	pair<np,np> split_cmp(np a,F cmp,T v){
		return split_sub<true>(a,cmp,v);
	}
	pair<np,np> split(np a,N v){
		return split_cmp(a,less<N>(),v);
	}
	//cmp(x,v)=false になる最初の x を根にして返す
	//そのようなものがない場合は false が返ってくる
	//FHC2022 Final E/range_set/rect_set
	template<class F,class T>
	bool lower_bound_cmp(np&a,F cmp,T v){
		auto [x,y]=split_sub<false>(a,cmp,v);
		if(y){
			a=y;
			return true;
		}else{
			//not verified?
			a=x;
			return false;
		}
	}
	bool lower_bound(np&a,N v){
		return lower_bound_cmp(a,less<N>(),v);
	}
	//XIX Opencup GP of Zhejiang A
	//FHC2022 Final E/range_set/rect_set
	template<class F>
	void insert_cmp(np&x,F cmp,np v){
		assert(!v->l&&!v->r&&!v->p&&!v->rev);
		//auto [a,b]=split_cmp(x,f,v->x);
		//x=v->linklr(a,b);
		if(!x){
			x=v;
			return;
		}else{
			np p=0;
			bool l;
			while(x){
				x->push();
				p=x;
				if(cmp(x->x,v->x)){
					l=false;
					x=x->r;
				}else{
					l=true;
					x=x->l;
				}
			}
			if(l){
				p->linkl(v);
			}else{
				p->linkr(v);
			}
			x=v->splay();
		}
	}
	//XX Opencup GP of Wroclaw D
	//FHC2022 Final E/range_set/rect_set
	template<class F,class...Args>
	void emplace_cmp(np&x,F f,Args&&...args){
		insert_cmp(x,f,nn(forward<Args>(args)...));
	}
	//FHC2022 Final E/range_set/rect_set
	template<class...Args>
	void emplace(np&x,Args&&...args){
		emplace_cmp(x,less<N>(),forward<Args>(args)...);
	}
	//XX Opencup GP of Wroclaw D
	pair<np,np> erase_sub(np x){
		x->splay();
		if(x->l)x->l->p=0;
		if(x->r)x->r->p=0;
		freenode(x);
		return mp(x->l,x->r);
	}
	//CF Dytechlab Cup 2022 G
	void erase(np&x){
		auto [a,b]=erase_sub(x);
		x=merge(a,b);
	}
	//FHC2022 Final E/range_set/rect_set
	//less,eq,
	template<class F,class T,class G>
	bool erase_cmp_eq(np&x,F f,G g,T v){
		if(lower_bound_cmp(x,f,v)&&g(x->x,v)){
			erase(x);
			return true;
		}
		return false;
	}
	//FHC2022 Final E/range_set/rect_set
	template<class T>
	bool erase(np&x,T v){
		return erase_cmp_eq(x,less<N>(),equal_to<N>(),v);
	}
	//Petrozavodsk 2020w Day9 H
	np isolate(np x){
		x->splay();
		if(x->l)x->l->p=0;
		if(x->r)x->r->p=0;
		np res=merge(x->l,x->r);
		x->x.single();
		x->clear();
		return res;
	}
	template<class t>
	np build(vc<t> v){
		vc<np> cur;
		for(auto z:v)cur.pb(nn(z));
		while(cur.size()>1){
			int s=cur.size();
			vc<np> nx((s+1)/2);
			for(int i=0;i<s;i+=2){
				if(i+1<s)nx[i/2]=merge(cur[i],cur[i+1]);
				else nx[i/2]=cur[i];
			}
			swap(nx,cur);
		}
		return cur[0];
	}
	/*
	//NOT VERIFIED
	//lower_bound したものを根に移して node を返す.
	//lower_bound の結果が end だと空が返ってくるらしい
	//USACO2021 USOPEN Platinum A
	template<class F>
	np lower_bound_cmp(np a,F cmp,N v){
		auto [x,y]=split_cmp(a,cmp,v);
		np res=nullptr;
		if(y)res=y->left();
		merge(x,res);
		if(res)res->splay();
		return res;
	}
	*/
	//XIX Opencup GP of Zhejiang A
	//a-b なる部分を取り出し,x,y(a-b),z を返す
	//a と b が異なる木に属する,また,a と b の順序がおかしい場合,何が起きるかは不明
	tuple<np,np,np> split_range(np a,np b){
		{//debug
			a->splay();
			b->splay();
			int lastpos;
			auto c=a;
			while(c&&c!=b){
				lastpos=c->pos();
				c=c->p;
			}
			assert(c==b);
			assert(lastpos==-1);
		}
		a->splay();
		np x=a->l;
		a->cutl();
		b->splay();
		np z=b->r;
		b->cutr();
		return mt(x,b,z);
	}
	//CF743F(TLE)
	//The 2022 ICPC Asia Nanjing Regional Contest H
	template<class F>
	void weighted_merge_rec_cmp(np&tar,F f,np x){
		if(!x)return;
		x->push();
		np l=x->l,r=x->r;
		x->x.single();
		x->clear();
		weighted_merge_rec_cmp(tar,f,l);
		insert_cmp(tar,f,x);
		weighted_merge_rec_cmp(tar,f,r);
	}
	template<class F>
	np weighted_merge_cmp(np a,F f,np b){
		if(!a)return b;
		if(!b)return a;
		if(a->x.len<b->x.len)swap(a,b);
		weighted_merge_rec_cmp(a,f,b);
		return a;
	}
	//Petrozavodsk 2020w Day9 C
	void enumerate(np x,vc<N>&dst){
		if(!x)return;
		x->push();
		enumerate(x->l,dst);
		dst.pb(x->x);
		enumerate(x->r,dst);
	}
	template<class F>
	bool iteration(np x,F f){
		if(!x)return false;
		x->push();
		if(iteration(x->l,f))return true;
		if(f(x))return true;
		if(iteration(x->r,f))return true;
		return false;
	}
	/* deprecated
	//Petrozavodsk 2020w Day9 H
	template<class F>
	np insert(np r,np x,F f){
		np a,b;tie(a,b)=split(r,f,x->x);
		return merge(merge(a,x),b);
	}
	template<class F,class...Args>
	np insert(np r,F f,Args&&...args){
		np x=nn(forward<Args>(args)...);
		np a,b;tie(a,b)=split(r,f,x->x);
		return merge(merge(a,x),b);
	}
	//左の列の根は右端とは限らない!
	//右の列の根は左端だと思う
	template<class F,class...Args>
	pair<np,np> split(np a,F f,Args&&...args){
		if(!a)return {0,0};
		np b=a->find(f,forward<Args>(args)...);
		if(b){
			np c=b->l;
			return {c,b->cutl()};
		}
		return {a,0};
	}
	//GCJ2022 Round2 D
	tuple<np> split_by_len(np a){
		return a;
	}
	template<class...Args>
	auto split_by_len(np a,int len,Args...args){
		assert((!a&&len==0)||inc(0,len,a->x.len));
		auto [b,c]=split(a,&N::find_by_len,len);
		assert(len==0);
		return tuple_cat(tuple{b},split_by_len(c,args...));
	}
	//Petrozavodsk 2020w Day9 C
	template<class F>
	np weighted_merge_rec(np x,np tar,F f){
		if(!x)return tar;
		x->push();
		tar=weighted_merge_rec(x->l,tar,f);
		tar=weighted_merge_rec(x->r,tar,f);
		x->x.single();
		x->clear();
		return insert(tar,x,f);
	}
	//Petrozavodsk 2020w Day9 C
	template<class F>
	np weighted_merge(np a,np b,F f){
		if(!a)return b;
		if(!b)return a;
		if(a->x.sz<b->x.sz)swap(a,b);
		return weighted_merge_rec(b,a,f);
	}
	*/
};
//デフォルトコンストラクターが null node になっているべき (例えば len=0)
//N::reverse
//N::push→ pushl,pushr
//副作用なし,1個の子にpush
//N::clear
//lazy tagを消去
//N::single
//ノード単体の情報を元に部分木情報を初期化
//N::updatel,updater
//N::find
//find はその部分木内に目標とするノードがあるかどうかを返す
//split のやり方を変えたい
//max_right のノリで split をする
//split_cmp は cmp(x,v) が true になる最大の x を見つけてそれで分離
//↓deprecared
//split は find で見つけたものが右の部分木の left になるように分離する
//普通に a<b を渡すと lower_bound と同じ効果が得られる
//split_by_len で左 len 個とそれ以外に分離する
//find_by_len という比較関数が定義されていないと破壊

struct N{
	int t,x;
	N(){}
	N(int a,int b):t(a),x(b){}
	void reverse(){}
	void pushl(N&){
	}
	void pushr(N&){
	}
	void clear(){
	}
	void single(){
	}
	void updatel(const N&){
	}
	void updater(const N&){
	}
	bool operator<(const N&r)const{return t<r.t;}
};

bool dbg=false;

void slv(){
	int n,m;
	if(dbg){
		n=rand_int(2,10);
		m=rand_int(1,10);
	}else{
		cin>>n>>m;
	}
	splaytree<N> t;
	using np=splaytree<N>::np;
	vc<np> ls(n);
	rep(i,n)ls[i]=t.nn(-inf+i,i);
	vi cur=vid(n);
	for(int i=2;i<=2*m;i+=2){
		int a;
		if(dbg){
			a=rand_int(n-1);
		}else{
			cin>>a;a--;
		}
		t.emplace(ls[cur[a]],i,a+1);
		t.emplace(ls[cur[a+1]],i,a);
		swap(cur[a],cur[a+1]);
	}
	vi pos(n);rep(i,n)pos[cur[i]]=i;
	vc<pi> ans;
	rep(i,n)if(pos[i]!=i){
		int j=cur[i];
		int z=-1;
		t.iteration(ls[i],[&](np x){
			if(t.lower_bound(ls[j],x->x)){
				if(ls[j]->x.t==x->x.t){
					z=x->x.t;
					dmp2(x->x.t,x->x.x,ls[j]->x.t,ls[j]->x.x);
					assert(x->x.x>ls[j]->x.x);
					ls[i]=x->splay();
					return true;
				}
			}
			return false;
		});
		assert(z!=-1);
		ans.eb(z-1,ls[j]->x.x);
		
		auto [il,ir]=t.erase_sub(ls[i]);
		auto [jl,jr]=t.erase_sub(ls[j]);
		ls[i]=t.merge(il,jr);
		ls[j]=t.merge(jl,ir);
		
		swap(pos[i],pos[j]);
		swap(cur[pos[i]],cur[pos[j]]);
	}
	rep(i,n){
		assert(ls[i]->right()->x.x==i);
		t.freetree(ls[i]);
	}
	if(!dbg){
		print(si(ans));
		for(auto [z,a]:ans){
			cout<<z<<" "<<a+1<<"\n";
		}
	}
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	
	if(dbg){
		while(1)slv();
	}else{
	//int t;cin>>t;rep(_,t)
		slv();
	}
}

提出情報

提出日時
問題 J - AMidA
ユーザ maroonrk
言語 C++ (GCC 9.2.1)
得点 400
コード長 22392 Byte
結果 AC
実行時間 194 ms
メモリ 77640 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 400 / 400
結果
AC × 3
AC × 57
セット名 テストケース
Sample 00_sample_01, 00_sample_02, 00_sample_03
All 00_sample_01, 00_sample_02, 00_sample_03, 01_randsmall_0, 01_randsmall_1, 01_randsmall_2, 01_randsmall_3, 02_rand_0, 02_rand_1, 02_rand_2, 02_rand_3, 03_randbig_0, 03_randbig_1, 03_randbig_2, 03_randbig_3, 03_randbig_4, 03_randbig_5, 04_randbigMsmall_0, 04_randbigMsmall_1, 04_randbigMsmall_2, 05_randMbigNsmall_0, 05_randMbigNsmall_1, 05_randMbigNsmall_2, 06_hand_01, 06_hand_02, 06_randmax_0, 06_randmax_1, 06_randmax_2, 07_stair_1, 07_stair_2, 07_stair_3, 07_stair_4, 07_stair_5, 07_stair_6, 07_stair_7, 08_stairarb_1, 08_stairarb_2, 08_stairarb_3, 08_stairarb_4, 08_stairarb_5, 08_stairarb_6, 08_stairarb_7, 09_radder_1, 10_binary_tree_1, 10_binary_tree_2, 10_binary_tree_3, 10_binary_tree_4, 11_perm_01, 11_perm_02, 11_perm_03, 11_perm_04, 11_perm_05, 11_perm_06, 11_perm_07, 11_perm_08, 11_perm_09, 11_perm_10
ケース名 結果 実行時間 メモリ
00_sample_01 AC 8 ms 3576 KiB
00_sample_02 AC 2 ms 3656 KiB
00_sample_03 AC 15 ms 11920 KiB
01_randsmall_0 AC 2 ms 3508 KiB
01_randsmall_1 AC 2 ms 3464 KiB
01_randsmall_2 AC 2 ms 3540 KiB
01_randsmall_3 AC 2 ms 3504 KiB
02_rand_0 AC 2 ms 3620 KiB
02_rand_1 AC 4 ms 3704 KiB
02_rand_2 AC 2 ms 3684 KiB
02_rand_3 AC 3 ms 3676 KiB
03_randbig_0 AC 27 ms 7800 KiB
03_randbig_1 AC 23 ms 7708 KiB
03_randbig_2 AC 18 ms 7648 KiB
03_randbig_3 AC 21 ms 7772 KiB
03_randbig_4 AC 181 ms 47320 KiB
03_randbig_5 AC 167 ms 47128 KiB
04_randbigMsmall_0 AC 39 ms 21364 KiB
04_randbigMsmall_1 AC 24 ms 14112 KiB
04_randbigMsmall_2 AC 29 ms 19836 KiB
05_randMbigNsmall_0 AC 94 ms 22524 KiB
05_randMbigNsmall_1 AC 78 ms 20408 KiB
05_randMbigNsmall_2 AC 99 ms 23904 KiB
06_hand_01 AC 5 ms 3660 KiB
06_hand_02 AC 2 ms 3660 KiB
06_randmax_0 AC 165 ms 47388 KiB
06_randmax_1 AC 158 ms 47528 KiB
06_randmax_2 AC 187 ms 47464 KiB
07_stair_1 AC 113 ms 35904 KiB
07_stair_2 AC 97 ms 36140 KiB
07_stair_3 AC 105 ms 34452 KiB
07_stair_4 AC 102 ms 38948 KiB
07_stair_5 AC 107 ms 39668 KiB
07_stair_6 AC 101 ms 33468 KiB
07_stair_7 AC 103 ms 34404 KiB
08_stairarb_1 AC 146 ms 77568 KiB
08_stairarb_2 AC 152 ms 77640 KiB
08_stairarb_3 AC 121 ms 51264 KiB
08_stairarb_4 AC 117 ms 52716 KiB
08_stairarb_5 AC 126 ms 52672 KiB
08_stairarb_6 AC 109 ms 49688 KiB
08_stairarb_7 AC 160 ms 63508 KiB
09_radder_1 AC 67 ms 38236 KiB
10_binary_tree_1 AC 108 ms 49520 KiB
10_binary_tree_2 AC 106 ms 49556 KiB
10_binary_tree_3 AC 106 ms 49552 KiB
10_binary_tree_4 AC 105 ms 49444 KiB
11_perm_01 AC 99 ms 43216 KiB
11_perm_02 AC 105 ms 38420 KiB
11_perm_03 AC 104 ms 38308 KiB
11_perm_04 AC 102 ms 43384 KiB
11_perm_05 AC 109 ms 49568 KiB
11_perm_06 AC 107 ms 49440 KiB
11_perm_07 AC 189 ms 49628 KiB
11_perm_08 AC 189 ms 49604 KiB
11_perm_09 AC 192 ms 49608 KiB
11_perm_10 AC 194 ms 49516 KiB