P14963 [LBA-OI R2 B] 何意味 题解

题目链接

一道神秘思维题。

不难发现本题的 1 操作等价于两个子串都尽可能进行何意味操作后,剩下的串是否相当。(这也是我思维的截至点)。

因此变成相邻消除,很难维护。考虑异或,但是不难发现异或具有交换律,因此不可行。

考虑改变思路,现在我们需要开发出一种运算,满足其具有结合律,不具有交换律。联想到了矩阵乘法。

考虑 \(2\times2\) 的矩阵

\[\begin{pmatrix} a,b\\ c,d \end{pmatrix} \]

对于相同的矩阵,显然有

\[\begin{pmatrix} a,b\\ c,d \end{pmatrix} \times \begin{pmatrix} a,b\\ c,d \end{pmatrix} = \begin{pmatrix} 1,0\\ 0,1 \end{pmatrix} \]

后者,就相当于矩阵里面的 1

因此有

\[\left\{ \begin{align} a^2+bc=1\qquad\\ ab+bd=0\qquad\\ ac+cd=0\qquad\\ bc+d^2=1\qquad \end{align} \right. \]

胡乱构造一下,得到矩阵可以变成:

\[\begin{pmatrix} a,1-a\\ 1+a,-a \end{pmatrix} \]

接下来用线段树维护矩阵就好了。

Code

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define File(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define LL long long
#define fi first
#define se second
const unsigned int mod = 1e9 + 7;
const int N = 5e5 + 10;
struct matrix{
	unsigned int a[2][2];
	matrix(){a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0;}	
	void new_mat(unsigned x){
		a[0][0] = x;
		a[0][1] = 1 - x;
		a[1][0] = 1 + x;
		a[1][1] = -x;
		return ;
	}
	matrix operator * (const matrix &oth) const{
		matrix c;
		c.a[0][0] = a[0][0] * oth.a[0][0] + a[0][1] * oth.a[1][0];
		c.a[0][1] = a[0][0] * oth.a[0][1] + a[0][1] * oth.a[1][1];
		c.a[1][0] = a[1][0] * oth.a[0][0] + a[1][1] * oth.a[1][0];
		c.a[1][1] = a[1][0] * oth.a[0][1] + a[1][1]* oth.a[1][1];
		return c;
	}
	bool operator == (const matrix &oth) const{
		if(a[0][0] != oth.a[0][0]) return 0;
		if(a[0][1] != oth.a[0][1]) return 0;
		if(a[1][0] != oth.a[1][0]) return 0;
		if(a[1][1] != oth.a[1][1]) return 0;
		return 1;
	}
};
struct seg{
	matrix tre[N << 2];
	#define ls (p*2)
	#define rs (p*2+1)
	unsigned int a[N];
	void pushup(int p){
		tre[p] = tre[ls] * tre[rs];
		return ;
	}
	void build(int pl,int pr,int p){
		if(pl == pr){
			tre[p].new_mat(a[pl]);
			return ;
		}
		int mid = pl + pr >> 1;
		build(pl,mid,ls);
		build(mid+1,pr,rs);
		pushup(p);
	}
	void update(int x,int pl,int pr,int p,int k){
		if(pl == pr){
			tre[p].new_mat(k);
			return;
		}
		int mid = pl + pr >> 1;
		if(x <= mid) update(x,pl,mid,ls,k);
		else update(x,mid+1,pr,rs,k);
		pushup(p);
		return ;
	}
	matrix query(int L,int R,int pl,int pr,int p){
		if(L <= pl && pr <= R){
			return tre[p];
		}
		int mid = pl + pr >> 1;
		if(L <= mid && mid < R)
			return query(L,R,pl,mid,ls) * query(L,R,mid+1,pr,rs);
		else if(L <= mid)
			return query(L,R,pl,mid,ls);
		else
			return query(L,R,mid+1,pr,rs);
	}
	#undef ls
	#undef rs
}s,t;
unsigned int hsh[N];
mt19937 rnd(time(0));
void init(){
	for(int i=0;i<=N-10;i++){
		hsh[i] = rnd();
	}
	return ;
}
int n,Q;
int main()
{
	IOS;
	init();
	cin >> n >> Q;
	for(int i=1;i<=n;i++){
		int x;
		cin >> x;
		s.a[i] = hsh[x];
	}
	for(int i=1;i<=n;i++){
		int x;
		cin >> x;
		t.a[i] = hsh[x];
	}
	s.build(1,n,1);
	t.build(1,n,1);
	while(Q -- ){
		int op;
		cin >> op;
		if(op == 1){
			int l,r,l_,r_;
			cin >> l >> r >> l_ >> r_;
			matrix S = s.query(l,r,1,n,1);
			matrix T = t.query(l_,r_,1,n,1);
			if(S == T)cout << "Yes\n";
			else cout << "No\n";
		}
		else if(op == 2){
			int p,x;
			cin >> p >> x;
			s.update(p,1,n,1,hsh[x]);
		}
		else if(op == 3){
			int p,x;
			cin >> p >> x;
			t.update(p,1,n,1,hsh[x]);
		}
	}

	return 0;
}
posted @ 2026-01-22 20:54  WinterXorSnow  阅读(1)  评论(0)    收藏  举报