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;
}

浙公网安备 33010602011771号