CF1849C题解
先来看这样一个例子。
原串:001101,000111。
设原串为
这是因为 0,而 0 存在,当这一区间被排序后,0,就与
那么,当排序区间是
所以可以记录下每一个 0 右边第一个 1 的位置 1 左边第一个 0 的位置
但这样做会遇到一个问题。还是上面的例子,对
统计区间时可使用 unordered_map,需要手写哈希函数。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=2e5+2;
int t,n,m,nxt[N],pre[N],ans;
char s[N];
LL hsh(int x,int y){return 1LL*(n+1)*x+y;}
unordered_map<LL,int>vis;
int main()
{
cin>>t;
while(t--)
{
vis.clear();
ans=0;
cin>>n>>m;
nxt[n+1]=n+1;
scanf("%s",s+1);
for(int i=1;i<=n;i++)
if(s[i]=='1')
pre[i]=pre[i-1];
else
pre[i]=i;
for(int i=n;i;i--)
if(s[i]=='0')
nxt[i]=nxt[i+1];
else
nxt[i]=i;
for(int i=1;i<=m;i++)
{
int l,r;
cin>>l>>r;
l=nxt[l];
r=pre[r];
if(l>r)
l=r=0;
if(!vis[hsh(l,r)])
{
ans++;
vis[hsh(l,r)]=1;
}
}
cout<<ans<<'\n';
}
return 0;
}