java线段树求调 没过样例
查看原帖
java线段树求调 没过样例
1110115
chronobox楼主2024/3/6 16:45
import java.io.*;
import java.util.*;
import java.math.*;
public class Main {
	static PrintWriter cout = new PrintWriter(System.out);
	static FastReader cin = new FastReader();
	static final int N = 200010;
	static int [] pre = new int [N*4], suf = new int [N*4], max = new int [N*4], ls = new int [N*4], rs = new int [N*4], size = new int [N*4];
	static int lc (int u) {
		return u >> 1;
	}
	static int rc (int u) {
		return u >> 1 | 1;
	}
	static void pushup (int u) {		
		if(rs[lc(u)] == ls[rc(u)]) {
			//左区间右端点和右区间左端点相同 取两边的最大
			max[u] = Math.max(max[lc(u)], max[rc(u)]);
		}
		else {
			//否则 在左最大区间 右最大区间 左最大后缀+右最大前缀 三者取最大
			max[u] = Math.max(Math.max(max[lc(u)], max[rc(u)]),suf[lc(u)] + pre[rc(u)]);
		}
		//左边可以取整段 且 左区间右端点 != 右区间左端点 更新最大前缀 = 整段左区间 + 右区间最大前缀 
		if(size[lc(u)] == pre[lc(u)] && rs[lc(u)] != ls[rc(u)]) pre[u] = size[lc(u)] + pre[rc(u)];
		//否则 最大前缀为左区间最大前缀
		else pre[u] = pre[lc(u)];
		//右边可以取整段 且 左区间右端点 != 右区间左端点 更新最大后缀 = 整段右区间 + 左区间最大后缀 
		if(size[rc(u)] == suf[rc(u)] && rs[lc(u)] != ls[rc(u)]) suf[u] = size[rc(u)] + suf[lc(u)];
		//否则 最大后缀为右区间最大后缀
		else suf[u] = suf[rc(u)];
		ls[u] = ls[lc(u)];
		rs[u] = rs[rc(u)];
		size[u] = size[lc(u)] + size[rc(u)];
	}
	static void build(int u, int l, int r) {
		if(l == r) {
			size[u] = ls[u] = rs[u] = max[u] = pre[u] = suf[u] = 1;
			return;
		}
		int mid = (l + r) >> 1;
		build(lc(u), l, mid);
		build(rc(u), mid + 1, r);
		pushup(u);
	}
	static void change(int u, int l, int r, int pos) {
		if(l == r) {
			ls[u] ^= 1;
			rs[u] ^= 1;
			return;
		}
		int mid = (l + r) >> 1;
		if(pos <= mid) change(lc(u), l , mid, pos);
		else change(rc(u), mid + 1, r, pos);
		pushup(u);
	}
	public static void main(String[] args) {
		int t = 1;
		//t = cin.nextInt();
		while(t-- > 0) {
			solve();
			cout.flush();
		}
	}
	static void solve() {
		int n = cin.nextInt(), q = cin.nextInt();
		build(1, 1, n);
		while(q-- > 0) {
			int x = cin.nextInt();
			change(1, 1, n, x);
			cout.println(max[1]);
		}
	}
}
class FastReader{
	StringTokenizer st;
	BufferedReader br;
	public FastReader() {
		br = new BufferedReader(new InputStreamReader(System.in));
	}
	String next() {
		while(st == null || !st.hasMoreElements()) {
			try {
				st = new StringTokenizer(br.readLine());
			}catch (IOException e) {
				e.getStackTrace();
			}
		}
		return st.nextToken();
	}
	int nextInt() {
		return Integer.parseInt(next());
	}
}

2024/3/6 16:45
加载中...