Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem L: RMQ 2

Problem

長さ$N$の2つの数列$A$と$B$が与えられる。はじめ、数列$A$の$i$項目は$a_i$であり、数列$B$の$i$項目は$b_i$である。

以下のような形式の命令文が合計$Q$個与えられるので、与えられた順に処理を行うプログラムを作成せよ。

各命令文は3つの整数$x,y,z$で表される。

数列$A$の$y$項目の値を$z$にする。 ($x=1$のとき)

数列$B$の$y$項目の値を$z$にする。 ($x=2$のとき)

数列$A$の$y$項目から$z$項目の中で最小の値を見つけて報告する。 ($x=3$のとき)

数列$B$の$y$項目から$z$項目の中で最小の値を見つけて報告する。 ($x=4$のとき)

数列$A$を、数列$B$と全く同じになるように変更する。 ($x=5$のとき)

数列$B$を、数列$A$と全く同じになるように変更する。 ($x=6$のとき)

Input

入力は以下の形式で与えられる。

$N$

$a_{1}$ $a_{2}$ ... $a_{N}$

$b_{1}$ $b_{2}$ ... $b_{N}$

$Q$

$x_1$ $y_1$ $z_1$

$x_2$ $y_2$ $z_2$

...

$x_Q$ $y_Q$ $z_Q$

Constraints

入力は以下の条件を満たす。

$2 \le N \le 2 \times 10^5$

$2 \le Q \le 2 \times 10^5$

$1 \le a_i \le 10^9$

$1 \le b_i \le 10^9$

$1 \le x_i \le 6$

$1 \le y_i \le N $ ($1 \le x_i \le 4$のとき)

$y_i = -1$ ($x_i=5, 6$のとき)

$1 \le z_i \le 10^9$ ($x_i=1, 2$のとき)

$y_i \le z_i \le N$ ($x_i=3, 4$のとき)

$z_i = -1$ ($x_i=5, 6$のとき)

入力はすべて整数

Output

$x=3$または$x=4$の命令文が入力で与えられる度に、見つけた値を1行に出力する。

Sample Input 1

5
1 3 5 7 9
6 2 3 2 6
10
1 3 4
3 4 5
4 2 3
5 -1 -1
2 3 8
3 2 5
4 3 3
1 1 1
6 -1 -1
3 1 5

Sample Output 1

7
2
2
8
1

Solution in C (judge verdict: Accepted)

#include<stdio.h>
#include <stdlib.h>
#define ll long long
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define INF ((1LL<<62)-(1LL<<31))
#define min(p,q)((p)<(q)?(p):(q))


//*
//遅延セグ木ここから
//↓ここを変える
typedef struct sayouso{ll aa,ab,bb,ba;}sayouso;
typedef struct atai{ll a,b;}atai;
//↑ここを変える

typedef struct node{sayouso T;atai x;}node;
node *lsegN,*lseg;
ll lsegNUM,lsegk;

//↓ここから変える
sayouso sid={0,0,0,0};
atai aid={INF,INF};
atai xx(atai x,atai y){
	atai ret;
	ret.a=min(x.a,y.a);
	ret.b=min(x.b,y.b);
	return ret;
}
atai Tx(sayouso T,atai x){
	atai ret;
	if(T.aa)ret.a=T.aa;
	else if(T.ab)ret.a=x.b;
	else ret.a=x.a;
	if(T.bb)ret.b=T.bb;
	else if(T.ba)ret.b=x.a;
	else ret.b=x.b;
	return ret;
}
sayouso TT(sayouso S,sayouso T){
	sayouso ret;
	if(S.ab){
		ret.aa=T.bb?:0;
		ret.ab=!T.ba&&!T.bb;
	}else if(S.aa){
		ret.aa=S.aa;
		ret.ab=0;
	}else{
		ret.aa=T.aa;
		ret.ab=T.ab;
	}
	if(S.ba){
		ret.bb=T.aa?:0;
		ret.ba=!T.ab&&!T.aa;
	}else if(S.bb){
		ret.bb=S.bb;
		ret.ba=0;
	}else{
		ret.bb=T.bb;
		ret.ba=T.ba;
	}
	return ret;
}
sayouso fT(sayouso T,ll k){
	return T;
}
//↑ここまで変える

//要素数(2ベキ)でこれを呼ぶ
void lseguse(ll n){
	lsegN=(node*)calloc(2*n,sizeof(node));
	lsegNUM=n;
	lseg=lsegN+lsegNUM;
	lsegk=0;while(n/=2)lsegk++;
	rep(i,1,2*lsegNUM){
		lsegN[i].x=aid;
		lsegN[i].T=sid;
	}
}
//lseg[i].xに値を与えてから初期化
void lseginit(){
	for(ll i=lsegNUM-1;i>0;i--)lsegN[i].x=xx(lsegN[2*i].x,lsegN[2*i+1].x);
}
void lsegupdatesub(ll l,ll r,sayouso T,ll i,ll cl,ll cr,ll ck){
	if(l>=r)return;
	//disjointなとき
	if(cr<=l||r<=cl)return;
	//完全に含むとき
	if(l<=cl&&cr<=r){
		lsegN[i].T=TT(T,lsegN[i].T);
		return;
	}
	//どちらでもないとき
	//遅延伝播
	lsegN[2*i  ].T=TT(lsegN[i].T,lsegN[2*i  ].T);
	lsegN[2*i+1].T=TT(lsegN[i].T,lsegN[2*i+1].T);
	//再帰的に更新
	ll cm=(cl+cr)/2;
	lsegupdatesub(l,r,T,2*i  ,cl,cm,ck-1);
	lsegupdatesub(l,r,T,2*i+1,cm,cr,ck-1);
	//自身のnodeを更新
	lsegN[i].x=xx(Tx(fT(lsegN[2*i].T,ck-1),lsegN[2*i].x),Tx(fT(lsegN[2*i+1].T,ck-1),lsegN[2*i+1].x));
	lsegN[i].T=sid;
}
void lsegupdate(ll l,ll r,sayouso T){lsegupdatesub(l,r,T,1,0,lsegNUM,lsegk);}
atai lsegcalcsub(ll l,ll r,ll i,ll cl,ll cr,ll ck){
	if(l>=r)return aid;
	//完全に含むとき
	if(l<=cl&&cr<=r)return Tx(fT(lsegN[i].T,ck),lsegN[i].x);

	ll cm=(cl+cr)/2;
	//遅延伝播(変更はないので配るだけで良い)
	lsegN[2*i  ].T=TT(lsegN[i].T,lsegN[2*i  ].T);
	lsegN[2*i+1].T=TT(lsegN[i].T,lsegN[2*i+1].T);
	lsegN[i].x=Tx(fT(lsegN[i].T,ck),lsegN[i].x);
	lsegN[i].T=sid;

	//左側だけ
	if(r<=cm)return lsegcalcsub(l,r,2*i  ,cl,cm,ck-1);
	//右側だけ
	if(cm<=l)return lsegcalcsub(l,r,2*i+1,cm,cr,ck-1);
	//両方
	return xx(lsegcalcsub(l,r,2*i,cl,cm,ck-1),lsegcalcsub(l,r,2*i+1,cm,cr,ck-1));
}
atai lsegcalc(ll l,ll r){return lsegcalcsub(l,r,1,0,lsegNUM,lsegk);}
//遅延セグ木ここまで
//*/

int main(){
	int n;
	scanf("%d",&n);
	lseguse(1<<18);
	rep(i,1,n+1)scanf("%lld",&lseg[i].x.a);
	rep(i,1,n+1)scanf("%lld",&lseg[i].x.b);
	lseginit();
	int q;
	scanf("%d",&q);
	while(q--){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		sayouso T={0,0,0,0};
		if(x==1){
			T.aa=z;
			lsegupdate(y,y+1,T);
		}else if(x==2){
			T.bb=z;
			lsegupdate(y,y+1,T);
		}else if(x==3){
			printf("%d\n",lsegcalc(y,z+1).a);
		}else if(x==4){
			printf("%d\n",lsegcalc(y,z+1).b);
		}else if(x==5){
			T.ab=1;
			lsegupdate(1,n+1,T);
		}else if(x==6){
			T.ba=1;
			lsegupdate(1,n+1,T);
		}
	}
}