1 10 10 0 0 0 1 1 0 1 0 1 1 1 0 2 3 0 5 2 2 2 4 0 4 0 3 6 2 3 7 4 2 8 1 0 5 0 5 6 3 3 9
5 2 6 5
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3397
题意:给你一个01字符串,对一段区间可能的操作有置0,置1,翻转,询问1的个数,询问最多有多少个连续的1。。。
分析:这题其实就是把各种操作合在一道题上面了,所以代码长一些而已,难度还是一样的。。。就不解释了,不懂的见前面几道题,或者看看代码啥的
代码:
#include<cstdio> #include<iostream> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int mm=111111; int dly[mm<<2],rev[mm<<2],sum[mm<<2]; int mla[mm<<2],mlb[mm<<2],lma[mm<<2],lmb[mm<<2],rma[mm<<2],rmb[mm<<2]; void set(int rt,int op,int len) { sum[rt]=(op-1)*len; mla[rt]=lma[rt]=rma[rt]=(op-1)*len; mlb[rt]=lmb[rt]=rmb[rt]=(2-op)*len; dly[rt]=op,rev[rt]=0; } void reverse(int rt,int len) { sum[rt]=len-sum[rt]; swap(mla[rt],mlb[rt]); swap(lma[rt],lmb[rt]); swap(rma[rt],rmb[rt]); rev[rt]^=1; } void pushdown(int rt,int l1,int l2) { if(rev[rt]) { if(dly[rt])dly[rt]=3-dly[rt]; else reverse(rt<<1,l1),reverse(rt<<1|1,l2); rev[rt]=0; } if(dly[rt]) { set(rt<<1,dly[rt],l1),set(rt<<1|1,dly[rt],l2); dly[rt]=0; } } void pushup(int rt,int l1,int l2) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; mla[rt]=max(rma[rt<<1]+lma[rt<<1|1],max(mla[rt<<1],mla[rt<<1|1])); mlb[rt]=max(rmb[rt<<1]+lmb[rt<<1|1],max(mlb[rt<<1],mlb[rt<<1|1])); lma[rt]=lma[rt<<1],rma[rt]=rma[rt<<1|1]; lmb[rt]=lmb[rt<<1],rmb[rt]=rmb[rt<<1|1]; if(lma[rt]>=l1)lma[rt]+=lma[rt<<1|1]; if(lmb[rt]>=l1)lmb[rt]+=lmb[rt<<1|1]; if(rma[rt]>=l2)rma[rt]+=rma[rt<<1]; if(rmb[rt]>=l2)rmb[rt]+=rmb[rt<<1]; } void build(int l,int r,int rt) { dly[rt]=rev[rt]=0; if(l==r) { scanf("%d",&sum[rt]); mla[rt]=lma[rt]=rma[rt]=sum[rt]; mlb[rt]=lmb[rt]=rmb[rt]=!sum[rt]; return; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt,m-l+1,r-m); } void updata(int L,int R,int op,int l,int r,int rt) { if(L<=l&&R>=r) { if(op)set(rt,op,r-l+1); else reverse(rt,r-l+1); return; } int m=(l+r)>>1; pushdown(rt,m-l+1,r-m); if(L<=m)updata(L,R,op,lson); if(R>m)updata(L,R,op,rson); pushup(rt,m-l+1,r-m); } int query(int L,int R,int op,int l,int r,int rt) { if(L<=l&&R>=r)return op?sum[rt]:mla[rt]; int m=(l+r)>>1,ret=0; pushdown(rt,m-l+1,r-m); if(op) { if(L<=m)ret+=query(L,R,op,lson); if(R>m)ret+=query(L,R,op,rson); } else { if(R<=m)ret=query(L,R,op,lson); else if(L>m)ret=query(L,R,op,rson); else ret=max(min(R,m+lma[rt<<1|1])-max(L,m-rma[rt<<1]+1)+1, max(query(L,R,op,lson),query(L,R,op,rson))); } pushup(rt,m-l+1,r-m); return ret; } int main() { int i,a,b,n,m,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); build(0,n-1,1); while(m--) { scanf("%d%d%d",&i,&a,&b); if(i<3)updata(a,b,(i+1)%3,0,n-1,1); else printf("%d\n",query(a,b,4-i,0,n-1,1)); } } return 0; }date: 2013-11-5
#include <iostream> #include <cstdio> using namespace std; #define REP(i,n) for(int i=0;i<n;i++) #define N 100010 struct node { node *ls, *rs; int num[2], sz; int change, turn; int ms[2], lms[2], rms[2]; node(){} node(node a, node b) { ls = &a, rs = &b; up(); } void changeIt(int c) { change = c; ms[c] = lms[c] = rms[c] = num[c] = sz; c^=1; ms[c] = lms[c] = rms[c] = num[c] = 0; turn = 0;//赋值后记得清空翻转标记 } void turnIt() { turn ^=1; swap(num[0],num[1]); swap(ms[0],ms[1]); swap(lms[0],lms[1]); swap(rms[0],rms[1]); } void up() { REP(i,2) { num[i] = ls->num[i] + rs->num[i]; ms[i] = max( ls->rms[i]+rs->lms[i],max(ls->ms[i], rs->ms[i])); lms[i] = ls->lms[i]; rms[i] = rs->rms[i]; if(lms[i]>=ls->sz)lms[i]+=rs->lms[i]; if(rms[i]>=rs->sz)rms[i]+=ls->rms[i]; } } void down() { if(change>=0) { ls->changeIt(change); rs->changeIt(change); change = -1; } if(turn) { ls->turnIt(); rs->turnIt(); turn = 0; } } }; node mem[N<<2], *root, *cur; node *new_node() { cur->change = -1; cur->turn = 0; cur->sz = 1; return cur++; } void init() { cur = mem; } void build(int l, int r, node *&rt) { rt = new_node(); if(l+1>=r) { scanf("%d",&rt->change); rt->changeIt(rt->change); return ; } int m =(l+r)>>1; build(l,m,rt->ls); build(m,r,rt->rs); rt->sz = rt->ls->sz + rt->rs->sz; rt->up(); } void update(int a, int b, int op, int l, int r, node *rt) { if(a<=l && b+1>=r) { if(op<2)rt->changeIt(op); else rt->turnIt(); return ; } int m =(l+r)>>1; rt->down(); if(a<m )update(a,b,op,l,m,rt->ls); if(b>=m)update(a,b,op,m,r,rt->rs); rt->up(); } node query(int a, int b, int l, int r, node *rt) { if(a<=l && b+1>=r)return *rt; int m = (l+r)>>1; rt->down(); node ret; if(b<m ) ret = query(a,b,l,m,rt->ls); else if(a>=m) ret = query(a,b,m,r,rt->rs); else ret = node( query(a,b,l,m,rt->ls),query(a,b,m,r,rt->rs)); rt->up(); return ret; } int main(int argc, char ** argv) { int t, n, m, op, a, b; scanf("%d", &t); while (t--) { scanf("%d%d",&n,&m); init(); build(0,n,root); while (m--) { scanf("%d%d%d", &op, &a, &b); if(op<3)update(a,b,op,0,n,root); else { node now = query(a,b,0,n,root); if(op==3)printf("%d\n",now.num[1]); else printf("%d\n",now.ms[1]); } } } return 0; }