zoukankan      html  css  js  c++  java
  • [COCI2010-2011#6] STEP

    Description

    sol:

    这道题类似区间最大子段和。我们维护 lm, rm, ms,分别表示左右最长子串,全局最长子串。pushup的时候,计算ms时,应该为左右儿子内部的ms与跨越左右区间的ms的最大值。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    using namespace std;
    
    const int N = 2e5 + 100;
    
    struct Node {
    	int l, r;
    	int lm, rm, ms;
    } tr[N << 2];
    
    int n, q;
    bool a[N];
    
    void pushup(int u) {
    	Node & ls = tr[u << 1], rs = tr[u << 1 | 1];
    	tr[u].lm = ls.lm;
    	if( ls.lm == ls.r - ls.l + 1 && a[ls.r] ^ a[rs.l])
    		tr[u].lm = max(tr[u].lm, ls.lm + rs.lm);
    	tr[u].rm = rs.rm;
    	if( rs.rm == rs.r - rs.l + 1 && a[rs.l] ^ a[ls.r])
    	    tr[u].rm = max(tr[u].rm, rs.rm + ls.rm);
    	tr[u].ms = max(ls.ms, rs.ms);
    	if( a[ls.r] ^ a[rs.l]) {
    		tr[u].ms = max(tr[u].ms, ls.rm + rs.lm);
    	}
    }
    
    void change(int u, int k) {
    	if( tr[u].l == tr[u].r) {
    		a[tr[u].l] ^= 1;
    		return;
    	}
    	int mid = tr[u].l + tr[u].r >> 1;
    	if(k <= mid)	change(u << 1, k);
    	else change(u << 1 | 1, k);
    	pushup(u);
    } 
    
    void build(int u, int l, int r) {
    	tr[u].l = l, tr[u].r = r;
    	tr[u].ms = tr[u].lm = tr[u].rm = 1;
    	if(l == r)	return;
    	int mid = l + r >> 1;
    	build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r); 
    }
    
    int main()
    {
    	scanf("%d%d", &n, &q);
    	build(1, 1, n);
    	while(q --) {
    		int k;
    		scanf("%d", &k);
    		change(1, k);
    		printf("%d
    ", tr[1].ms);
    	}
    	return 0;
    }
    /*
    3 1
    2
    
    */
    
  • 相关阅读:
    GridView动态创建TemplateField的回发问题
    ASP.NET页面生命周期
    php图片叠加
    php文件下载
    mysql 常用操作命令
    转载:图解SQL的Join
    利用iframe来做无刷新上传
    php抽象和接口的区别
    php 循环打开目录读取文件
    mysql存储引擎的对比(一)
  • 原文地址:https://www.cnblogs.com/wyy0804/p/13769280.html
Copyright © 2011-2022 走看看