https://codeforces.com/problemset/problem/1562/D1
题意:
给出一个由1和-1构成的序列,有若干次询问,每次询问一个区间,问最少删除几个数,满足区间内剩下的序列的奇数项减去偶数项=0
结论:
1、若区间原本的奇数项-偶数项的和=0,答案是0
否则,
2、若区间长度为奇数,答案是1
3、若区间长度是偶数,答案是2
2的证明:
设(b_i)表示一个长度为奇数的区间去掉第i项之后的奇数项减去偶数项
因为(b_i)有偶数个数,所以(b_i)一定是偶数
若第(i)个数=第(i+1)个数,那么(b_i=b_{i+1})。这个好理解,因为相邻的这2个数是一个样的,去掉谁都一样。
若第(i)个数(
eq)第(i+1)个数,那么(|b_i-b_{i+1}|=2)。这是因为去掉这2个数中的某个数,对于(i)前面和(i+1)后面的数的影响都是一样的。又因为他们两个不一样,所以差值是2。
接下来我们的目标是证明必然存在一个(i)满足(b_i=0)
设区间长度为(n)
若(b_1)或者(b_n=0),那么就删除第(1)或者第(n)个数即可
若(b_1)和(b_n)都(
eq0),设(x)表示第2个数-第3个数+第4个数-第5个数……,则(x)必然是奇数
(b_1=-x±1),(b_n=x±1),可以得出(b_1)和(b_n)不会同时大于0或者同时小于0
即(b_1)和(b_n)必然一正一负
而又因为(|b_i-b_{i+1}|=2)且(b_i)一定是偶数,所以必然存在一个(i)满足(b_i=0)
3的证明:
设(b_i)表示一个长度为偶数的区间去掉第i项之后的奇数项减去偶数项
因为(b_i)有奇数个数,所以(b_i)一定是奇数
所以删除1个肯定不行
删除1个之后区间长度变为奇数,由结论2可得,再删除1个必然有解
#include<bits/stdc++.h>
#define N 300002
char s[N];
int a[N];
int sum(int l,int r)
{
if(l&1) return a[r]-a[l-1];
return a[l-1]-a[r];
}
int main()
{
int T,n,m,l,r;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%s",&n,&m,s+1);
for(int i=1;i<=n;++i) a[i]=s[i]=='+' ? 1 : -1;
for(int i=1;i<=n;++i)
if(i&1) a[i]=a[i-1]+a[i];
else a[i]=a[i-1]-a[i];
while(m--)
{
scanf("%d%d",&l,&r);
if(!sum(l,r)) printf("0
");
else if((r-l)&1) printf("2
");
else printf("1
");
}
}
}