P2572 [SCOI2010]序列操作 珂朵莉树

题目链接:https://www.luogu.com.cn/problem/P2572
题目大意:
图片说明
思路:珂朵莉树搞一搞,好像数据加强了,只能30分,会T。

#include <bits/stdc++.h>
#define ll long long
#define sit set<node>::iterator
using namespace std;

struct node{
    int l, r;
    mutable ll val;
    int operator<(const node &a) const{
        return l<a.l;
    }
    node(int L, int R, ll Val): l(L), r(R), val(Val){}
    node(int L) : l(L){}
};

struct odTree{
    set<node> s;
    sit Split(int pos){//一个节点分裂[l, r]->[l, pos-1]+[pos, r]
        sit it=s.lower_bound(node(pos));
        if(it!=s.end()&&it->l==pos) return it;
        --it;
        int l=it->l, r=it->r;
        ll val=it->val;
        s.erase(it);
        s.insert(node(l, pos-1, val));
        return s.insert(node(pos, r, val)).first;
    }
    void Assign(int l, int r, ll val){//区间赋值
        sit it2=Split(r+1), it1=Split(l);
        s.erase(it1, it2);
        s.insert(node{l, r, val});
    }
    void Add(int l, int r){//区间[l, r] a[i]取反
        sit it2=Split(r+1), it1=Split(l);
        for(sit it=it1; it!=it2; ++it) it->val^=1;
    }
    ll Query(int l, int r){//求[l, r]的1的个数
        sit it2=Split(r+1), it1=Split(l);
        ll res=0;
        for(sit it=it1; it!=it2; ++it){
            if(it->val==1){
                res+=((it->r)-(it->l)+1);
            }
        }
        return res;
    }
    ll Query2(int l, int r){//求[l, r]的0连续1的个数
        sit it2=Split(r+1), it1=Split(l);
        ll res=0, tmp=0;
        for(sit it=it1; it!=it2; ){
            if(it->val==1){
                tmp=0;
                while(it!=it2&&it->val==1){
                    tmp+=((it->r)-(it->l)+1);
                    ++it;
                }
                res=max(res, tmp);
            }
            else{
                ++it;
            }
        }
        return res;
    }

}Tree;

inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

int main(){

    int n, m, val;
    n=read(), m=read();
    for(int i=1; i<=n; i++){
        val=read();
        Tree.s.insert(node(i, i, (ll)val));
    }
    Tree.s.insert(node(n+1, n+1, -1));
    for(int i=1; i<=m; i++){
        int op=read(), x=read(), y=read();
        x++, y++;
        if (op == 0) Tree.Assign(x, y, 0);
        else if (op == 1) Tree.Assign(x, y, 1);
        else if (op == 2) Tree.Add(x, y);
        else if (op == 3) printf("%lld\n", Tree.Query(x, y));
        else printf("%lld\n", Tree.Query2(x, y));
    }

    return 0;
}
全部评论

相关推荐

伟大的烤冷面被普调:暨大✌🏻就是强
点赞 评论 收藏
分享
Allen好Iverson:我看牛客都是20-30k的 这个3.9k爆出来有点,哈哈哈哈
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
12-17 17:43
Java抽象带篮子:绝绝子暴风吸入啊
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务