Solution - P7809 [JRKSJ R2] 01 序列

校内模拟赛 T3,恭喜 yuruilin2026 神犇拿下首 A。

思路

一眼线段树,然而线段树被卡了。

于是思考每次查询 \(\mathcal{O}(1)\) 的做法,一眼 ST 表。

思考本题的“LIS”构造,显然是一堆 \(0\) 接上一堆 \(1\)。于是用前缀和统计两种数,ST 表构造的时候利用性质往一个序列前面塞 \(0\) 或者往后面塞 \(1\),询问同理。

第二问简单,不赘述了。

#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 1000006
using namespace std;

namespace IO{//by cyffff
	int len=0;
	char ibuf[(1<<20)+1],*iS,*iT,out[(1<<26)+1];
	#define gh() (iS==iT?iT=(iS=ibuf)+fread(ibuf,1,(1<<20)+1,stdin),(iS==iT?EOF:*iS++):*iS++)
	#define reg register
	inline int read(){
		reg char ch=gh();
		reg int x=0;
		reg char t=0;
		while(ch<'0'||ch>'9')   t|=ch=='-',ch=gh();
		while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();
		return t?-x:x;
	}
	inline void putc(char ch){
		out[len++]=ch;
	}
	template<class T>
	inline void write(T x){
		if(x<0)putc('-'),x=-x;
		if(x>9)write(x/10);
		out[len++]=x%10+48;
	}
	inline void flush(){
		fwrite(out,1,len,stdout);
		len=0;
	}
}
using IO::read;
using IO::write;
using IO::flush;
using IO::putc;

int Log2[N];
int pre1[N], pre2[N], st1[N][21], st2[N][21];
int a[N];
int n, q;

#define len (r-l+1)

int main(){
	//freopen("in.txt", "r", stdin);
	n = read(), q = read();
	for(rint i = 1; i <= n; ++i) a[i] = read();
	for(rint i = 2; i <= n; ++i)
		Log2[i] = Log2[i>>1]+1;
	for(rint i = 1; i <= n; ++i){
		pre1[i] = pre1[i-1], pre2[i] = pre2[i-1];
		if(a[i] == 0) ++pre1[i];
		else          ++pre2[i];
		st1[i][0] = 1, st2[i][0] = 0;
	}
	for(rint t = 1; t <= 20; ++t)
		for(rint i = 1; i <= n; ++i){
			rint l = i, mid = i+(1<<t-1)-1, r = min(i+(1<<t)-1, n);
			st1[i][t] = max(pre1[mid]-pre1[l-1]+st1[mid+1][t-1], st1[l][t-1]+pre2[r]-pre2[mid]);
			st2[i][t] = st2[l][t-1] || st2[mid+1][t-1] || (pre1[mid]-pre1[l-1]>0 && pre2[r]-pre2[mid]>0);
		}
	while(q--){
		rint op, l, r;
		op = read(), l = read(), r = read();
		if(op == 1){
			rint ans = max(st1[l][Log2[len]]+pre2[r]-pre2[l+(1<<Log2[len])-1], 
		               st1[r-(1<<Log2[len])+1][Log2[len]]+pre1[r-(1<<Log2[len])]-pre1[l-1]);
		    write(ans), putc('\n');
		}
		else{
			rint ans = (st2[l][Log2[len]] || st2[r-(1<<Log2[len])+1][Log2[len]])+1;
			write(ans), putc('\n');
		}
	}
	flush();
	return 0;
}

posted @ 2025-04-21 20:04  Hootime  阅读(13)  评论(0)    收藏  举报