BZOJ 1858: [Scoi2010]序列操作 [线段树]

可恶两个标记传反顺序了一直到现在....

睡觉了睡觉了

这是我写过最漂亮的线段树


 

[补题解]

想法很简单的线段树,同时维护0,1两个信息

因为要求最长0,1序列所以要维护最长,从左开始最长,从右开始最长

然后为了转移还要维护一个区间长度(该死一开始没维护这个长度后来有的地方加上有的地方没加然后一堆bug改了好久)

我用了合并和返回节点的方法,要不然写三个询问太恶心了

关于两个标记,显然打修改标记时要清空翻转标记,我打翻转标记时把修改标记也翻转了,所以下传标记如果先修改后翻转的话就成“翻转了两次”啊啊啊啊啊啊啊啊,以后一定要想清楚

以后要多独立写几道复杂的题增强玛丽!

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
#define lson lc,l,mid
#define rson rc,mid+1,r
const int N=1e5+5;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}
int n,Q,op,a,b;
struct Node{
    int mx[2],lm[2],rm[2],sum[2];
    int tag,rev;
    int len;
    Node():tag(-1),rev(0),len(0){mx[0]=mx[1]=lm[0]=lm[1]=rm[0]=rm[1]=sum[0]=sum[1]=0;}
}t[N<<2];

inline Node Merge(Node a,Node b){
    Node re;
    re.sum[1]=a.sum[1]+b.sum[1];
    re.mx[1]=max( a.rm[1]+b.lm[1] , max(a.mx[1],b.mx[1]) );
    re.lm[1]=a.lm[1]+ (a.lm[1]==a.len ? b.lm[1] : 0);
    re.rm[1]=b.rm[1]+ (b.rm[1]==b.len ? a.rm[1] : 0);

    re.sum[0]=a.sum[0]+b.sum[0];
    re.mx[0]=max( a.rm[0]+b.lm[0] , max(a.mx[0],b.mx[0]) );
    re.lm[0]=a.lm[0]+ (a.lm[0]==a.len ? b.lm[0] : 0);
    re.rm[0]=b.rm[0]+ (b.rm[0]==b.len ? a.rm[0] : 0);

    re.len=a.len+b.len;
    return re;
}
inline void pushUp(int x){t[x]=Merge(t[lc],t[rc]);}

void paint(int x,int v){
    t[x].tag=v;
    t[x].rev=0;
    t[x].sum[v]=t[x].mx[v]=t[x].lm[v]=t[x].rm[v]=t[x].len;
    v^=1;
    t[x].sum[v]=t[x].mx[v]=t[x].lm[v]=t[x].rm[v]=0;
}
void rever(int x){
    t[x].rev^=1;
    if(t[x].tag!=-1) t[x].tag^=1;
    swap(t[x].sum[0],t[x].sum[1]);
    swap(t[x].mx[0] ,t[x].mx[1]);
    swap(t[x].lm[0] ,t[x].lm[1]);
    swap(t[x].rm[0] ,t[x].rm[1]);
}

void pushDown(int x){
    if(t[x].rev){
        rever(lc);
        rever(rc);
        t[x].rev=0;
    }
    if(t[x].tag!=-1){
        paint(lc,t[x].tag);
        paint(rc,t[x].tag);
        t[x].tag=-1;
    }
}

void build(int x,int l,int r){
    if(l==r) t[x].len=1,paint(x,read());
    else{
        build(lson);
        build(rson);
        pushUp(x);
    }
}

void segCov(int x,int l,int r,int ql,int qr,int v){
    if(ql<=l&&r<=qr) paint(x,v);
    else{
        pushDown(x);
        if(ql<=mid) segCov(lson,ql,qr,v);
        if(mid<qr) segCov(rson,ql,qr,v);
        pushUp(x);
    }
}

void segRev(int x,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr) rever(x);
    else{
        pushDown(x);
        if(ql<=mid) segRev(lson,ql,qr);
        if(mid<qr) segRev(rson,ql,qr);
        pushUp(x);
    }
}

int segSum(int x,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr) return t[x].sum[1];
    else{
        pushDown(x);
        int ans=0;
        if(ql<=mid) ans+=segSum(lson,ql,qr);
        if(mid<qr) ans+=segSum(rson,ql,qr);
        return ans;
    }
}

Node segQue(int x,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr) return t[x];
    else{
        pushDown(x);
        if(qr<=mid) return segQue(lson,ql,qr);
        if(mid<ql) return segQue(rson,ql,qr);
        return Merge(segQue(lson,ql,qr),segQue(rson,ql,qr));
    }
}

int main(){
    freopen("in","r",stdin);
    n=read();Q=read();
    build(1,1,n);
    while(Q--){
        op=read();a=read()+1;b=read()+1;
        if(op==0)       segCov(1,1,n,a,b,0);
        else if(op==1) segCov(1,1,n,a,b,1);
        else if(op==2) segRev(1,1,n,a,b);
        else if(op==3) printf("%d\n",segSum(1,1,n,a,b));
        else if(op==4) printf("%d\n",segQue(1,1,n,a,b).mx[1]);
    }
}

 

转载于:https://www.cnblogs.com/candy99/p/6487194.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值