80pts求调

P2572 [SCOI2010] 序列操作

MujinH @ 2024-01-31 19:48:48

优良码风,求调。

#include<iostream>
#include<cstdio>

#define BUFSIZE 1000005
inline char getch_()
{
    static char buf[BUFSIZE], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, BUFSIZE, stdin), p1 == p2) ? EOF : *p1 ++ ;
}
char outbuf[BUFSIZE], *outp = outbuf;
inline void putch(const char &c)
{
    if (outp - outbuf == BUFSIZE) fwrite(outbuf, 1, outp - outbuf, stdout), outp = outbuf;
    *outp ++ = c;
}
#ifndef ONLINE_JUDGE
#define getch_ getchar
#define putch putchar
#endif
template<typename Type>
inline bool read(Type &x)
{
    char c = getch_();
    bool t; x = t = 0;
    if (c == EOF) return false;
    while (c < '0' || c > '9') t |= (c == '-'), c = getch_();
    while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getch_();
    x = t ? -x : x;
    return true;
}
inline int read(char *c)
{
    char *i = c;
    while (*i = getch_(), *i == ' ' || *i == '\n');
    while (*i != ' ' && *i != '\n') * ++ i = getch_();
    *i = '\0';
    return i - c;
}
template<typename Type>
inline void write(Type x, const char &c)
{
    static int s[35], top; top = 0;
    if (x < 0) x = -x, putch('-');
    do s[top ++ ] = x % 10, x /= 10;
    while (x);
    while (top) putch(s[ -- top] + '0');
    putch(c);
}
inline void write(const char *c) {while (*c) putch(*c ++ );}

using namespace std;
using ll=long long;
const int N=1e5+50,M=1e5+50;

int n,m;
int arr[N];

struct node{
    int val,maxx1,maxx0;
    int Llen1,Rlen1;
    int Llen0,Rlen0;
}tree[N*4];
int tag_ass[N*4],tag_neg[N*4];

int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}

void add_tag_ass(int p,int pl,int pr,int x);
void add_tag_neg(int p,int pl,int pr);
void push_up(int p,int pl,int pr);
void push_down(int p,int pl,int pr);
void build(int p,int pl,int pr);
void update_ass(int p,int pl,int pr,int L,int R,int ass);
void update_neg(int p,int pl,int pr,int L,int R);
int query_val(int p,int pl,int pr,int L,int R);
int query_len(int p,int pl,int pr,int L,int R);

int main(){
    read(n),read(m);
    for(int i=1;i<=n;i++) read(arr[i]);
    build(1,1,n);
    while(m--){
        int opt,a,b;
        read(opt),read(a),read(b);
        a++,b++;
        if(opt==0) update_ass(1,1,n,a,b,0);
        if(opt==1) update_ass(1,1,n,a,b,1);
        if(opt==2) update_neg(1,1,n,a,b);
        if(opt==3) write(query_val(1,1,n,a,b),'\n');
        if(opt==4) write(query_len(1,1,n,a,b),'\n');
    }
    fwrite(outbuf,1,outp-outbuf,stdout);
    return 0;
}

void add_tag_ass(int p,int pl,int pr,int x){
    tag_ass[p]=x;
    if(tag_neg[p]) tag_neg[p]=0;
    if(x){
        tree[p].val=pr-pl+1;
        tree[p].Llen1=tree[p].Rlen1=tree[p].maxx1=pr-pl+1;
        tree[p].Llen0=tree[p].Rlen0=tree[p].maxx0=0;
    }else{
        tree[p].val=0;
        tree[p].Llen1=tree[p].Rlen1=tree[p].maxx1=0;
        tree[p].Llen0=tree[p].Rlen0=tree[p].maxx0=pr-pl+1;
    }
    return ;
}

void add_tag_neg(int p,int pl,int pr){
    int mid=(pl+pr)>>1;
    tag_neg[p]=!tag_neg[p];
    if(tag_ass[p]!=-1){
        add_tag_ass(ls(p),pl,mid,tag_ass[p]);
        add_tag_ass(rs(p),mid+1,pr,tag_ass[p]);
        tag_ass[p]=-1;
    }
    tree[p].val=pr-pl+1-tree[p].val;
    swap(tree[p].maxx1,tree[p].maxx0);
    swap(tree[p].Llen1,tree[p].Llen0);
    swap(tree[p].Rlen1,tree[p].Rlen0);
    return ;
}

void push_up(int p,int pl,int pr){
    int mid=(pl+pr)>>1;
    tree[p].val=tree[ls(p)].val+tree[rs(p)].val;
    if(tree[ls(p)].Llen1==mid-pl+1) tree[p].Llen1=mid-pl+1+tree[rs(p)].Llen1;
    else tree[p].Llen1=tree[ls(p)].Llen1;
    if(tree[rs(p)].Rlen1==pr-mid) tree[p].Rlen1=pr-mid+tree[ls(p)].Rlen1;
    else tree[p].Rlen1=tree[rs(p)].Rlen1;
    if(tree[ls(p)].Llen0==mid-pl+1) tree[p].Llen0=mid-pl+1+tree[rs(p)].Llen0;
    else tree[p].Llen0=tree[ls(p)].Llen0;
    if(tree[rs(p)].Rlen0==pr-mid) tree[p].Rlen0=pr-mid+tree[ls(p)].Rlen0;
    else tree[p].Rlen0=tree[rs(p)].Rlen0;
    tree[p].maxx1=max(tree[ls(p)].Rlen1+tree[rs(p)].Llen1,max(tree[p].Llen1,tree[p].Rlen1));
    tree[p].maxx0=max(tree[ls(p)].Rlen0+tree[rs(p)].Llen0,max(tree[p].Llen0,tree[p].Rlen0));
    tree[p].maxx1=max(tree[p].maxx1,max(tree[ls(p)].maxx1,tree[rs(p)].maxx1));
    tree[p].maxx0=max(tree[p].maxx0,max(tree[ls(p)].maxx0,tree[rs(p)].maxx0));
    return ;
}

void push_down(int p,int pl,int pr){
    int mid=(pl+pr)>>1;
    if(tag_ass[p]!=-1){
        add_tag_ass(ls(p),pl,mid,tag_ass[p]);
        add_tag_ass(rs(p),mid+1,pr,tag_ass[p]);
        tag_ass[p]=-1;
    }
    if(tag_neg[p]){
        add_tag_neg(ls(p),pl,mid);
        add_tag_neg(rs(p),mid+1,pr);
        tag_neg[p]=0;
    }
    return ;
}

void build(int p,int pl,int pr){
    tag_ass[p]=-1;
    if(pl==pr){
        if(arr[pl]){
            tree[p].val=1;
            tree[p].Llen1=tree[p].Rlen1=tree[p].maxx1=1;
            tree[p].Llen0=tree[p].Rlen0=tree[p].maxx0=0;
        }else{
            tree[p].val=0;
            tree[p].Llen1=tree[p].Rlen1=tree[p].maxx1=0;
            tree[p].Llen0=tree[p].Rlen0=tree[p].maxx0=1;
        }   
        return ;
    }
    int mid=(pl+pr)>>1;
    build(ls(p),pl,mid);
    build(rs(p),mid+1,pr);
    push_up(p,pl,pr);
    return ;
}

void update_ass(int p,int pl,int pr,int L,int R,int ass){
    if(L<=pl&&pr<=R){
        add_tag_ass(p,pl,pr,ass);
        return ;
    }
    push_down(p,pl,pr);
    int mid=(pl+pr)>>1;
    if(L<=mid) update_ass(ls(p),pl,mid,L,R,ass);
    if(mid<R) update_ass(rs(p),mid+1,pr,L,R,ass);
    push_up(p,pl,pr);
    return ;
}

void update_neg(int p,int pl,int pr,int L,int R){
    if(L<=pl&&pr<=R){
        add_tag_neg(p,pl,pr);
        return ;
    }
    push_down(p,pl,pr);
    int mid=(pl+pr)>>1;
    if(L<=mid) update_neg(ls(p),pl,mid,L,R);
    if(mid<R) update_neg(rs(p),mid+1,pr,L,R);
    push_up(p,pl,pr);
    return ;
}

int query_val(int p,int pl,int pr,int L,int R){
    if(L<=pl&&pr<=R) return tree[p].val;
    push_down(p,pl,pr);
    int mid=(pl+pr)>>1,res=0;
    if(L<=mid) res+=query_val(ls(p),pl,mid,L,R);
    if(mid<R) res+=query_val(rs(p),mid+1,pr,L,R);
    push_up(p,pl,pr);
    return res;
}

int query_len(int p,int pl,int pr,int L,int R){
    if(L<=pl&&pr<=R) return tree[p].maxx1;
    push_down(p,pl,pr);
    int mid=(pl+pr)>>1,maxx=0;
    if(L<=mid) maxx+=min(mid-L+1,tree[ls(p)].Rlen1);
    if(mid<R) maxx+=min(R-mid,tree[rs(p)].Llen1);
    if(L<=mid) maxx=max(maxx,query_len(ls(p),pl,mid,L,R));
    if(mid<R) maxx=max(maxx,query_len(rs(p),mid+1,pr,L,R));
    push_up(p,pl,pr);
    return maxx;
}

by nb_jzy @ 2024-01-31 20:23:04

建议重构。


|