列表

详情


NC50099. 白山茶与红玫瑰

描述

公元2019年6月22日,白山茶王国与红玫瑰王国展开大战,在世外仙境——天空花园处,双方军团一字排开,在维持一字长蛇阵的队形下双方战士陷入混战。
然而,为了操控整个战局,白山茶公主与红玫瑰女巫都会一种AOE魔法,使得受到魔法波及的战士"叛变"(白山茶战士变为红玫瑰战士,红玫瑰战士变为白山茶战士)。
可见,这场战争永远没有绝对的优劣势,局势瞬息万变。现在,白山茶公主邀请你协助她了解各个区块的战况。

输入描述

第一行一个整数n( 0 < n <= 105),表示白山茶战士和红玫瑰战士的数量和。
第二行n个只包含0、1的整数,为一字长蛇阵中的战士类别(1为白山茶战士,0为红玫瑰战士,下标从1开始)。
第三行一个整数m(0 < m <= 100001),表示施放魔法和询问战况的操作次数。
随后m行,每行三个整数op,x,y: (op {0,1};1 <= x <= y <= n )
    对于op=1,表示对下标属于闭区间[x,y]的战士施放魔法,使她们"叛变";
    对于op=0,表示询问下标属于闭区间[x,y]的连续最多的白山茶战士的数目。
注:此题请不要使用多组输入!

输出描述

对于每一次op=0的操作,输出区间内连续最多的白山茶战士数目。

示例1

输入:

4
1 0 1 0
5
0 1 4
1 2 3
0 1 4
1 3 3
0 4 4

输出:

1
2
0

说明:

0 1 4 : answer=1
1 2 3 : 1 1 0 0
0 1 4 : answer=2
1 3 3 : 1 1 1 0
0 4 4 : answer=0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 173ms, 内存消耗: 10572K, 提交时间: 2023-04-06 17:27:06

#include <iostream>
#include <cstring>

using namespace std;

using i64 = long long;

const int N = 100010;

struct Node {
    int l, r;
    int ls[2], ms[2], rs[2];
    bool rev;
} tr[N << 2];
int n, m;
int w[N];

void pushup(Node& u, const Node& l, const Node& r) {
   for (int i : {0, 1}) {
        u.ms[i] = max(l.ms[i], r.ms[i]);
        u.ms[i] = max(u.ms[i], l.rs[i] + r.ls[i]);
        u.ls[i] = l.ls[i];
        if (u.ls[i] == l.r - l.l + 1) u.ls[i] += r.ls[i];
        u.rs[i] = r.rs[i];
        if (u.rs[i] == r.r - r.l + 1) u.rs[i] += l.rs[i];
    }     
}

void pushup(int u) {
    pushup(tr[u], tr[u << 1], tr[u << 1 |1]); 
}

void pushrev(int u) {
    tr[u].rev ^= 1;
    swap(tr[u].ms[0], tr[u].ms[1]);
    swap(tr[u].ls[0], tr[u].ls[1]);
    swap(tr[u].rs[0], tr[u].rs[1]);
}

void pushdown(int u) {
    if (tr[u].rev) {
        pushrev(u << 1);
        pushrev(u << 1 | 1);
        tr[u].rev = 0;
    }
}

void build(int u, int l, int r) {
    tr[u] = {l, r};
    if (l == r) {
        int v = w[l];
        tr[u].ms[v] = tr[u].ls[v] = tr[u].rs[v] = 1;
        return;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);
}

void modify(int u, int l, int r) {
    if (tr[u].l >= l && tr[u].r <= r) return pushrev(u);
    int mid = tr[u].l + tr[u].r >> 1;
    pushdown(u);
    if (l <= mid) modify(u << 1, l, r);
    if (r > mid) modify(u << 1 | 1, l, r);
    pushup(u);
}

Node query(int u, int l, int r) {
    if (tr[u].l >= l && tr[u].r <= r) return tr[u];
    int mid = tr[u].l + tr[u].r >> 1;
    pushdown(u);
    if (r <= mid) return query(u << 1, l, r);
    if (l > mid) return query(u << 1 | 1, l, r);
    Node res;
    pushup(res, query(u << 1, l, r), query(u << 1 | 1, l, r));
    return res;
}

int main() {
    cin.tie(0)->sync_with_stdio(false);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> w[i];
    }
    build(1, 1, n);
    cin >> m;
    while (m--) {
        int op, l, r;
        cin >> op >> l >> r;
        if (op == 1) modify(1, l, r);
        else cout << query(1, l, r).ms[1] << '\n';
    }
    return 0;
}

C++14(g++5.4) 解法, 执行用时: 446ms, 内存消耗: 11740K, 提交时间: 2019-07-19 23:58:52

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ls x<<1
#define rs x<<1|1
const int N=1e5+100;
int n,m;
struct node
{
	int l,r,l1,r1,m1,l0,r0,m0,lzy;
} t[N<<2];
void pushup(int x)
{
	t[x].l1=t[ls].l1;
	if(t[ls].l1==t[ls].r-t[ls].l+1) t[x].l1+=t[rs].l1;
	t[x].r1=t[rs].r1;
	if(t[rs].r1==t[rs].r-t[rs].l+1) t[x].r1+=t[ls].r1;
	t[x].m1=t[ls].r1+t[rs].l1;
	t[x].m1=max(t[x].m1,max(t[ls].m1,t[rs].m1));
	
	t[x].l0=t[ls].l0;
	if(t[ls].l0==t[ls].r-t[ls].l+1) t[x].l0+=t[rs].l0;
	t[x].r0=t[rs].r0;
	if(t[rs].r0==t[rs].r-t[rs].l+1) t[x].r0+=t[ls].r0;
	t[x].m0=t[ls].r0+t[rs].l0;
	t[x].m0=max(t[x].m0,max(t[ls].m0,t[rs].m0));
}
void pushdown(int x)
{
	
	if(t[x].lzy)
	{
		t[ls].lzy^=1;
		t[rs].lzy^=1;
		t[x].lzy^=1;
		swap(t[ls].l0,t[ls].l1);
		swap(t[ls].r1,t[ls].r0);
		swap(t[ls].m0,t[ls].m1);
		swap(t[rs].l0,t[rs].l1);
		swap(t[rs].r1,t[rs].r0);
		swap(t[rs].m0,t[rs].m1);
		
	}
}
void build(int l,int r ,int x)
{
	t[x].l=l,t[x].r=r;
	if(l==r)
	{
		int v;
		cin>>v;
		if(v==1) t[x].l1=t[x].r1=t[x].m1=1;
		else t[x].l0=t[x].r0=t[x].m0=1;
		return ;
	}
	int mid=l+r>>1;
	build(l,mid,ls);
	build(mid+1,r,rs);
	pushup(x);
}
void update(int L,int R,int x)
{
	int l=t[x].l,r=t[x].r;
	if(L<=l&&r<=R)
	{
		t[x].lzy^=1;
		swap(t[x].l0,t[x].l1);
		swap(t[x].r1,t[x].r0);
		swap(t[x].m0,t[x].m1);
		return ;
	}
	pushdown(x);
	int mid=l+r>>1;
	if(L<=mid) update(L,R,ls);
	if(R>mid)update(L,R,rs);
	pushup(x);
}
int query(int L,int R,int x)
{
	int l=t[x].l,r=t[x].r;
	if(L<=l&&r<=R) return t[x].m1;
	pushdown(x);
	int mid=l+r>>1;
	if(R<=mid) return query(L,R,ls);//ls可以等于mid
	if(L>mid) return query(L,R,rs);
	int res1=query(L,R,ls);
	int res2=query(L,R,rs);
	int res3=min(mid-L+1,t[ls].r1)+min(R-mid,t[rs].l1);
	return max(res1,max(res2,res3));
}
int main()
{
	cin>>n;
	build(1,n,1);
	cin>>m;
	for(int i=1,op,x,y,z;i<=m;i++)
	{
		cin>>op>>x>>y;
		if(op==1)update(x,y,1);
		else cout<<query(x,y,1)<<endl; 
	}
	return 0;
}

上一题