当前位置: 代码迷 >> 综合 >> Codeforces Round #104 (Div. 1) E. Lucky Queries (线段树)
  详细解决方案

Codeforces Round #104 (Div. 1) E. Lucky Queries (线段树)

热度:99   发布时间:2023-12-17 03:24:13.0

题意:

        长度为n的47串,两种操作,一种是区间变换,即4变7,7变4,一种是询问,问最长的非严格递增子序列长度

思路:

        线段树维护即可,47可以抽象成01串,变换就是异或,存储全0串最长长度,全1串最长长度,000..111串长度,111…000串长度,变换就让全0和全1交换,000…111和111…000交换,然后pushup的时候全1和全0可以根据左右儿子直接相加得到,000….111和111…000可以由儿子推出

错误及反思:

代码:

#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N = 1001000;
int segtree[N<<2][4],lazy[N<<2];// 0 for 0-0 1 for 0-1 2 for 1-0 3 for 1-1
char s[N];
int n,m;void pushup(int rt){segtree[rt][0]=segtree[rt<<1][0]+segtree[rt<<1|1][0];segtree[rt][3]=segtree[rt<<1][3]+segtree[rt<<1|1][3];segtree[rt][1]=max(segtree[rt<<1][1]+segtree[rt<<1|1][3],segtree[rt<<1][0]+max(segtree[rt<<1|1][1],segtree[rt<<1|1][3]));segtree[rt][2]=max(segtree[rt<<1][2]+segtree[rt<<1|1][0],segtree[rt<<1][3]+max(segtree[rt<<1|1][2],segtree[rt<<1|1][0]));}void build(int l,int r,int rt){if(l==r){if(s[l]==1) segtree[rt][3]=1;else segtree[rt][0]=1;segtree[rt][2]=1;segtree[rt][1]=1;return ;}int m=(l+r)/2;build(lson);build(rson);pushup(rt);
}void Swap(int rt){swap(segtree[rt][0],segtree[rt][3]);swap(segtree[rt][1],segtree[rt][2]);
}
void pushdown(int rt){if(lazy[rt]){Swap(rt<<1); Swap(rt<<1|1);lazy[rt<<1]++; lazy[rt<<1|1]++;lazy[rt<<1]%=2;lazy[rt<<1|1]%=2;lazy[rt]=0;}
}void update(int L,int R,int l,int r,int rt){if(L<=l&&R>=r){Swap(rt);lazy[rt]++;lazy[rt]%=2;return ;}pushdown(rt);int m=(l+r)/2;if(L<=m) update(L,R,lson);if(R>m) update(L,R,rson);pushup(rt);
}int main(){scanf("%d%d",&n,&m);scanf("%s",s+1);for(int i=1;i<=n;i++)if(s[i]=='4') s[i]=0;else s[i]=1;build(1,n,1);while(m--){char t[10]; scanf("%s",t);if(t[0]=='c') printf("%d\n",max(max(segtree[1][1],segtree[1][0]),segtree[1][3]));else{int l,r; scanf("%d%d",&l,&r);update(l,r,1,n,1);}}
}
  相关解决方案