选举「elections」

前言

震惊,\(O(n^2)\)暴力竟可艹过64pts!

于是水一篇题解

有什么必然联系吗?

题目

【题目描述】

有一个长度为\(N\)的字符串\(S[1...N]\),它仅由CT两种字母组成。
现在有\(Q\)个查询,每个查询包含两个整数\(L\)\(R\),表示:设新字符串\(S'=S[L..,R]\) ,至少在\(S'\)
要删除多少个字符,才能保证:对于\(S'\)的每一个前缀与每一个后缀,其C的数量都不小于T的数
量。

【输入格式】

第一行有一个整数\(N\)
第二行有一个长度为\(N\)的字符串\(S\)
第三行有一个整数\(Q\)
在接下来的\(Q\)行中,每行有两个整数\(L\)\(R\),表示一组查询。

【输出格式】

对于每组查询输出一行,表示至少在\(S'\)中要删除多少个字符,才能保证题面要求。

【样例1 输入】

11
CCCTTTTTTCC
3
1 11
4 9
1 6

【样例1 输出】

4 6 3

【样例1 解释】

查询 \(\texttt{1:CCCTTTTTTCC}\)
查询 \(\texttt{2:TTTTTT}\)
查询 \(\texttt{3:CCCTTT}\)

【数据范围与约束】


测试点编号 \(N,Q\)
\(1\)~\(5\) \(N,Q\)\(\le 2\)$ \times 10^3$
\(6\)~\(15\) \(N,Q\)\(\le 7\)$ \times 10^4$
\(16\)~\(25\) \(N,Q\)\(\le 5\)$ \times 10^5$

讲解

把相同相邻字符捆起来然后暴力+优秀常数+信仰O2=64pts v

这作者太懒了吧

代码

#define lc (x<<1)
#define rc (x<<1|1)
struct SegmentTree
{
	struct node
	{
		int MAX,MIN,MF;
		node(){}
		node(int MAX1,int MIN1,int MF1){
			MAX = MAX1;
			MIN = MIN1;
			MF = MF1; 
		}
		node operator + (const node &A)const{
			return node(Max(MAX,A.MAX),Min(MIN,A.MIN),Max(Max(MF,A.MF),A.MAX - MIN));
		}
	}t[MAXN << 2];
	
	void Build(int x,int l,int r)
	{
		if(l == r) {t[x] = node(s[l],s[l],0);return;}
		int mid = (l+r) >> 1;
		Build(lc,l,mid);Build(rc,mid+1,r);
		t[x] = t[lc] + t[rc];
	}
	
	node Query(int x,int l,int r,int ql,int qr) 
	{
		if(ql <= l && r <= qr) return t[x];
		int mid = (l+r) >> 1;
		if(ql <= mid && mid+1 <= qr) return Query(lc,l,mid,ql,qr) + Query(rc,mid+1,r,ql,qr);
		if(ql <= mid) return Query(lc,l,mid,ql,qr);
		return Query(rc,mid+1,r,ql,qr);
	}
}st;

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read();
	scanf("%s",a+1);
	for(int i = 1;i <= n;++ i) s[i] = s[i-1] + (a[i] == 'C' ? 1 : -1);
	st.Build(1,0,n);
	for(int Q = Read(); Q ;-- Q)
	{
		int l = Read(),r = Read();
		Put(st.Query(1,0,n,l-1,r).MF - s[r] + s[l-1],'\n');
	}
	return 0;
}
posted @ 2020-11-29 11:05  皮皮刘  阅读(169)  评论(0编辑  收藏  举报