题目
题解思路
预处理出每个相同数之前的点和后继节点。
类似链表的结构。
如果我们将首节点的前节点设置为0后继节点设置为n+1
来保证数据合法性。
将每个节点的后继节点导入线段树,再让线段树处理区间最小值。
这样我们就可以完成查询操作了。
根据查询出来的值是否合法即可。
删除操作就类似链表删除某个节点。
将合法的前节点直接指向后继节点。
并且在线段树上修改即可。
这里用链表处理属实巧妙
AC代码
#include <bits/stdc++.h>
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 500010 ;
int n , q ;
int a[N] ;
int ne[N] ;
int la[N] ;
struct node
{
int l ,r , mi , sum;
}tee[4*N];
void in(int i , int t1 , int t2)
{
tee[i].l = t1 , tee[i].r = t2;
if ( t1 == t2 )
{
tee[i].sum = a[t1] ;
tee[i].mi = ne[t1] ;
return ;
}
int j = (t1+t2)/2;
in(i*2,t1,j);
in(i*2+1,j+1,t2);
tee[i].sum = tee[i*2].sum+tee[i*2+1].sum;
tee[i].mi = min(tee[i*2].mi , tee[i*2+1].mi);
}
long long sea( int i ,int t1 , int t2 )
{
if ( tee[i].l >= t1 && tee[i].r <= t2 )
return tee[i].mi;
long long sum = n+1 ;
if ( tee[i*2].r >= t1 )
sum = min(sea(i*2,t1,t2),sum);
if ( tee[i*2+1].l <= t2 )
sum = min(sea(i*2+1,t1,t2),sum);
return sum;
}
void _add( int i , int t1 , int t2 ,int vv )
{
int l = tee[i].l , r = tee[i].r ;
if ( l >= t1 && r <= t2 )
{
tee[i].mi = vv ;
return ;
}
if ( tee[i*2].r >= t1)
_add(i*2,t1,t2,vv);
if (tee[i*2+1].l <= t2)
_add(i*2+1,t1,t2,vv);
tee[i].sum = tee[i*2].sum + tee[i*2+1].sum ;
tee[i].mi = min(tee[i*2].mi , tee[i*2+1].mi ) ;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n >> q ;
for (int i = 1 ; i <= n ; i++ )
cin >> a[i] ;
unordered_map <int , int > mp ;
for (int i = 1 ; i <= n ; i++ )
{
if (mp[a[i]] == 0 )
{
mp[a[i]] = i ;
la[i] = 0 ;
ne[i] = n+1 ;
}else
{
la[i] = mp[a[i]];
ne[mp[a[i]]] = i ;
ne[i] = n+1 ;
mp[a[i]] = i ;
//cout << i << " " << la[i] << "\n" ;
}
}
/*
for (int i = 1 ; i <= n ; i++ )
{
cout << la[i] << " " ;
}
cout << "\n" ;
for (int i = 1 ; i <= n ; i++ )
{
cout << ne[i] << " " ;
}
cout << "\n" ;
*/
in(1,1,n);
while (q--)
{
int pp , t1 , t2 ;
cin >> pp ;
if ( pp == 1 )
{
cin >> t1 ;
int tt = la[t1] ;
int kk = ne[t1] ;
if ( kk != n+1 )
{
int jj = ne[kk] ;
_add(1,t1,t1,jj) ;
}
if ( tt != 0 )
{
_add(1,tt,tt,kk) ;
ne[tt] = kk ;
}
if ( kk != n+1 )
{
la[kk] = tt ;
}
}else
{
cin >> t1 >> t2 ;
long long tmp = sea(1,t1,t2);
//cout << tmp << "\n";
if ( tmp <= t2 && tmp >= t1 )
cout << "1\n" ;
else
cout << "0\n" ;
}
}
return 0 ;
}