zoukankan      html  css  js  c++  java
  • [SCOI2010]序列操作 BZOJ1858 线段树

    题目描述

    lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作:

    0 a b 把[a, b]区间内的所有数全变成0

    1 a b 把[a, b]区间内的所有数全变成1

    2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0

    3 a b 询问[a, b]区间内总共有多少个1

    4 a b 询问[a, b]区间内最多有多少个连续的1

    对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?

    输入输出格式

    输入格式:

    输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目

    第二行包括n个数,表示序列的初始状态

    接下来m行,每行3个数,op, a, b,(0<=op<=4,0<=a<=b<n)表示对于区间[a, b]执行标号为op的操作

    输出格式:

    对于每一个询问操作,输出一行,包括1个数,表示其对应的答案

    输入输出样例

    输入样例#1: 复制
    10 10
       0 0 0 1 1 0 1 0 1 1
       1 0 2
       3 0 5
       2 2 2
       4 0 4
       0 3 6
       2 3 7
       4 2 8
       1 0 5
       0 5 6
       3 3 9
    
    输出样例#1: 复制
    5
    2
    6
    5

    说明

    对于30%的数据,1<=n, m<=1000

    对于100%的数据,1<=n, m<=100000

    很刺激的线段树题目;

    注意赋值的操作的优先级>翻转的操作;

    还有很多细节要注意;

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<ctime>
    #include<deque>
    #include<stack>
    #include<functional>
    #include<sstream>
    //#include<cctype>
    //#pragma GCC optimize(2)
    using namespace std;
    #define maxn 300005
    #define inf 0x3f3f3f3f
    #define INF 9999999999
    #define rdint(x) scanf("%d",&x)
    #define rdllt(x) scanf("%lld",&x)
    #define rdult(x) scanf("%lu",&x)
    #define rdlf(x) scanf("%lf",&x)
    #define rdstr(x) scanf("%s",x)
    typedef long long  ll;
    typedef unsigned long long ull;
    typedef unsigned int U;
    #define ms(x) memset((x),0,sizeof(x))
    const long long int mod = 1e9 + 7;
    #define Mod 1000000000
    #define sq(x) (x)*(x)
    #define eps 1e-3
    typedef pair<int, int> pii;
    #define pi acos(-1.0)
    const int N = 1005;
    #define REP(i,n) for(int i=0;i<(n);i++)
    typedef pair<int, int> pii;
    inline ll rd() {
    	ll x = 0;
    	char c = getchar();
    	bool f = false;
    	while (!isdigit(c)) {
    		if (c == '-') f = true;
    		c = getchar();
    	}
    	while (isdigit(c)) {
    		x = (x << 1) + (x << 3) + (c ^ 48);
    		c = getchar();
    	}
    	return f ? -x : x;
    }
    
    ll gcd(ll a, ll b) {
    	return b == 0 ? a : gcd(b, a%b);
    }
    ll sqr(ll x) { return x * x; }
    
    /*ll ans;
    ll exgcd(ll a, ll b, ll &x, ll &y) {
    	if (!b) {
    		x = 1; y = 0; return a;
    	}
    	ans = exgcd(b, a%b, x, y);
    	ll t = x; x = y; y = t - a / b * y;
    	return ans;
    }
    */
    
    
    
    ll qpow(ll a, ll b, ll c) {
    	ll ans = 1;
    	a = a % c;
    	while (b) {
    		if (b % 2)ans = ans * a%c;
    		b /= 2; a = a * a%c;
    	}
    	return ans;
    }
    
    
    struct node {
    	int sum;
    	int Lw, Lb;// Lb:区间连续0的最大长度,Lw:连续1的最大长度
    	int llw, rlw;//llb:区间左端点连续0的最大长度,llw:区间左端点连续1的最大长度;
    	int llb, rlb;// rlb:区间右端点连续0的最大长度;rlw:区间右端点连续1的最大长度
    	int lazy, rev;// lazy:是否全部变为1/0;rev:翻转标记
    }tr[maxn<<2];
    int n, m;
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    #define mid ((l+r)>>1)
    void pushup(int l, int r, int rt) {
    	tr[rt].sum = tr[lson].sum + tr[rson].sum;
    
    	tr[rt].Lb = max(tr[lson].Lb, tr[rson].Lb);
    	tr[rt].Lw = max(tr[lson].Lw, tr[rson].Lw);
    
    	tr[rt].llb = tr[lson].llb;
    	tr[rt].llw = tr[lson].llw;
    	if (tr[lson].llw == mid - l + 1)tr[rt].llw += tr[rson].llw;
    	if (tr[lson].llb == mid - l + 1)tr[rt].llb += tr[rson].llb;
    
    	tr[rt].rlb = tr[rson].rlb;
    	tr[rt].rlw = tr[rson].rlw;
    	if (tr[rson].rlb == r - mid)tr[rt].rlb += tr[lson].rlb;
    	if (tr[rson].rlw == r - mid)tr[rt].rlw += tr[lson].rlw;
    
    	tr[rt].Lw = max(tr[rt].Lw, tr[lson].rlw + tr[rson].llw);
    	tr[rt].Lb = max(tr[rt].Lb, tr[lson].rlb + tr[rson].llb);
    }
    
    void down(int l, int r, int rt) {
    	int lazy = tr[rt].lazy, rev = tr[rt].rev;
    	int L1 = mid - l + 1, L2 = r - mid;
    	tr[rt].lazy = -1;
    	if (lazy == 0) {
    		tr[lson] = node { 0, 0, L1, 0, 0, L1, L1, 0, 0 };
    		tr[rson] = node{ 0,0,L2,0,0,L2,L2,0,0 };
    	}
    	else if (lazy == 1) {
    		tr[lson] = node{ L1,L1,0,L1,L1,0,0,1,0 };
    		tr[rson] = node{ L2,L2,0,L2,L2,0,0,1,0 };
    	}
    	if (rev) {
    		tr[rt].rev = 0;
    		int sum = tr[lson].sum;
    		int Lw = tr[lson].Lw, Lb = tr[lson].Lb;
    		int llw = tr[lson].llw, llb = tr[lson].llb;
    		int rlw = tr[lson].rlw, rlb = tr[lson].rlb;
    		tr[lson].sum = L1 - sum;
    		tr[lson].Lw = Lb; tr[lson].Lb = Lw;
    		tr[lson].llw = llb; tr[lson].rlw = rlb;
    		tr[lson].llb = llw; tr[lson].rlb = rlw;
    		tr[lson].rev ^= 1;
    
    		sum = tr[rson].sum;
    		Lw = tr[rson].Lw; Lb = tr[rson].Lb;
    		llw = tr[rson].llw; llb = tr[rson].llb;
    		rlw = tr[rson].rlw; rlb = tr[rson].rlb;
    		tr[rson].sum = L2 - sum;
    		tr[rson].Lw = Lb; tr[rson].Lb = Lw;
    		tr[rson].llw = llb; tr[rson].rlw = rlb;
    		tr[rson].llb = llw; tr[rson].rlb = rlw;
    		tr[rson].rev ^= 1;
    	  
    	}
    }
    
    void build(int l, int r, int rt) {
    	tr[rt].lazy = -1;
    	if (l == r) {
    		int x; rdint(x);
    		tr[rt] = node{ x,x,(x ^ 1),x,x,(x ^ 1),(x ^ 1),-1,0 };
    		return;
    	}
    	build(l, mid, lson); build(mid + 1, r, rson);
    	pushup(l, r, rt);
    }
    
    void upd1(int l, int r, int rt, int L, int R) {
    	if (L <= l && r <= R) {
    		int LL = r - l + 1;
    		tr[rt] = node{ 0,0,LL,0,0,LL,LL,0,0 };
    		return;
    	}
    	if (l > R || r < L)return;
    	down(l, r, rt);
    	upd1(l, mid, lson, L, R); upd1(mid + 1, r, rson, L, R);
    	pushup(l, r, rt);
    }
    
    void upd2(int l, int r, int rt, int L, int R) {
    	if (L <= l && r <= R) {
    		int LL = r - l + 1;
    		tr[rt] = node{ LL,LL,0,LL,LL,0,0,1,0 };
    		return;
    	}
    	if (l > R || r < L)return;
    	down(l, r, rt);
    	upd2(l, mid, lson, L, R); upd2(mid + 1, r, rson, L, R);
    	pushup(l, r, rt);
    }
    
    void upd3(int l, int r, int rt, int L, int R) {
    	if (L <= l && r <= R) {
    		int LL = r - l + 1, sum = tr[rt].sum, Lw = tr[rt].Lw, Lb = tr[rt].Lb;
    		int llw = tr[rt].llw, llb = tr[rt].llb;
    		int rlw = tr[rt].rlw, rlb = tr[rt].rlb;
    		tr[rt] = node{ LL - sum,Lb,Lw,llb,rlb,llw,rlw,tr[rt].lazy,(tr[rt].rev ^ 1) };
    		return;
    	}
    	if (l > R || r < L)return;
    	down(l, r, rt);
    	upd3(l, mid, lson, L, R);
    	upd3(mid + 1, r, rson, L, R);
    	pushup(l, r, rt);
    }
    
    int query1(int l, int r, int rt, int L, int R) {
    	if (L <= l && r <= R)return tr[rt].sum;
    	if (l > R || r < L)return 0;
    	down(l, r, rt);
    	return query1(l, mid, lson, L, R) + query1(mid + 1, r, rson, L, R);
    }
    
    node query2(int l, int r, int rt, int L, int R) {
    	if (L <= l && r <= R)return tr[rt];
    	if (l > R || r < L)return node{ 0 };
    	down(l, r, rt);
    	node LL = query2(l, mid, lson, L, R), RR = query2(mid + 1, r, rson, L, R), ans;
    	ans.sum = LL.sum + RR.sum;
    	ans.Lw = max(LL.Lw, RR.Lw);
    	ans.Lb = max(LL.Lb, RR.Lb);
    	ans.llw = LL.llw, ans.rlw = RR.rlw;
    	ans.llb = LL.llb, ans.rlb = RR.rlb;
    	if (LL.llb == mid - l + 1)ans.llb += RR.llb;
    	if (LL.llw == mid - l + 1)ans.llw += RR.llw;
    	if (RR.rlb == r - mid)ans.rlb += LL.rlb;
    	if (RR.rlw == r - mid)ans.rlw += LL.rlw;
    	ans.Lw = max(ans.Lw, LL.rlw + RR.llw);
    	ans.Lb = max(ans.Lb, LL.rlb + RR.llb);
    	return ans;
    }
    
    int main()
    {
    	//ios::sync_with_stdio(0);
    	rdint(n); rdint(m);
    	build(1, n, 1);
    	while (m--) {
    		int op, a, b;
    		rdint(op); rdint(a); rdint(b);
    		a++; b++;
    		if (op == 0)upd1(1, n, 1, a, b);
    		if (op == 1)upd2(1, n, 1, a, b);
    		if (op == 2)upd3(1, n, 1, a, b);
    		if (op == 3)cout << query1(1, n, 1, a, b) << endl;
    		if (op == 4)cout << query2(1, n, 1, a, b).Lw << endl;
    	}
    	return 0;
    }
    
    EPFL - Fighting
  • 相关阅读:
    JAVA多线程2 锁
    IE8标准模式下VML不能显示问题
    JAVA多线程1
    JAVA判断32位还是64位,调用不同的DLL
    JNA调用DLL
    如何提高执行力
    httpClient多线程请求
    【NodeJS】安装
    [转载]一个项目涉及到的50个Sql语句(整理版)
    resultMap中的collection集合出现只能读取一条数据的解决方法
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10118027.html
Copyright © 2011-2022 走看看