[SCOI2010]序列操作

來源:互聯網
上載者:User

標籤:long   mat   uil   void   else   swap   mes   main   現在   

https://www.zybuluo.com/ysner/note/1297872題面

\(lxhgww\)最近收到了一個\(01\)序列,序列裡麵包含了\(n\)個數,這些數要麼是\(0\),要麼是\(1\),現在對於這個序列有五種變換操作和詢問操作:

  • 0 a b 把\([a, b]\)區間內的所有數全變成\(0\)
  • 1 a b 把\([a, b]\)區間內的所有數全變成\(1\)
  • 2 a b 把\([a,b]\)區間內的所有數全部取反,也就是說把所有的\(0\)變成\(1\),把所有的\(1\)變成\(0\)
  • 3 a b 詢問\([a, b]\)區間內總共有多少個\(1\)
  • 4 a b 詢問\([a, b]\)區間內最多有多少個連續的\(1\)

對於每一種詢問操作,\(lxhgww\)都需要給出回答,聰明的程式員們,你們能協助他嗎?

  • \(n\leq10^5\)

    解析

    線段樹模板題。
    只是要維護許多資訊,考驗細節和代碼能力而已。
    蒟蒻維護了\(12\)個:
    \(lt1[x]\)這一段左邊有多少個連續的\(1\);
    \(rt1[x]\)這一段右邊有多少個連續的\(1\);
    \(lt0[x]\)這一段左邊有多少個連續的\(0\);
    \(rt0[x]\)這一段右邊有多少個連續的\(0\);
    \(tag0[x]\)這一段是否全部為\(0\);
    \(tag1[x]\)這一段是否全部為\(1\);
    \(t1[x]\)這一段最多有多少個連續的\(1\);
    \(t0[x]\)這一段最多有多少個連續的\(0\);
    \(s[x]\)這一段有多少個\(1\)
    \(la0[x],la1[x],la2[x]\)前三個操作的懶標記。

難度集中在資訊合并:
講了沒意思,有需要自己看代碼吧。

我是不會承認我調了\(3h\)只因沒有意識到兩個操作\(2\)是可以抵消的。。。

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define ll long long#define re register#define il inline#define ls x<<1#define rs x<<1|1#define fp(i,a,b) for(re int i=a;i<=b;i++)#define fq(i,a,b) for(re int i=a;i>=b;i--)using namespace std;const int N=4e5+100;int n,m,t1[N],t0[N],lt1[N],rt1[N],lt0[N],rt0[N],s[N],tag0[N],tag1[N],la0[N],la1[N],la2[N];il int max(re int x,re int y){return x>y?x:y;}il int min(re int x,re int y){return x<y?x:y;}struct dat{int t1,lt1,rt1,tag1;};il int gi(){  re int x=0,t=1;  re char ch=getchar();  while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar();  if(ch==‘-‘) t=-1,ch=getchar();  while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-48,ch=getchar();  return x*t;}il void upd(re int x){  s[x]=s[ls]+s[rs];  t1[x]=max(t1[ls],t1[rs]);  t1[x]=max(t1[x],rt1[ls]+lt1[rs]);  t0[x]=max(t0[ls],t0[rs]);  t0[x]=max(t0[x],rt0[ls]+lt0[rs]);  if(tag1[ls]) lt1[x]=lt1[ls]+lt1[rs];else lt1[x]=lt1[ls];  if(tag1[rs]) rt1[x]=rt1[rs]+rt1[ls];else rt1[x]=rt1[rs];  if(tag0[ls]) lt0[x]=lt0[ls]+lt0[rs];else lt0[x]=lt0[ls];  if(tag0[rs]) rt0[x]=rt0[rs]+rt0[ls];else rt0[x]=rt0[rs];  t1[x]=max(t1[x],max(lt1[x],rt1[x]));  t0[x]=max(t0[x],max(lt0[x],rt0[x]));  tag1[x]=tag1[ls]&tag1[rs];tag0[x]=tag0[ls]&tag0[rs];}il void Build(re int x,re int l,re int r){  if(l==r)    {      lt1[x]=rt1[x]=s[x]=t1[x]=tag1[x]=gi();      if(!t1[x]) t0[x]=lt0[x]=rt0[x]=tag0[x]=1;      return;    }  re int mid=l+r>>1;  Build(ls,l,mid);Build(rs,mid+1,r);  upd(x);}il void cover(re int x,re int l,re int r,re int op){  if(op==0)    {      s[x]=t1[x]=lt1[x]=rt1[x]=tag1[x]=0;      t0[x]=lt0[x]=rt0[x]=r-l+1;      tag0[x]=la0[x]=1;la1[x]=la2[x]=0;    }  if(op==1)    {      s[x]=t1[x]=lt1[x]=rt1[x]=r-l+1;      t0[x]=lt0[x]=rt0[x]=tag0[x]=0;      tag1[x]=la1[x]=1;la0[x]=la2[x]=0;    }  if(op==2)    {      swap(t1[x],t0[x]);swap(lt1[x],lt0[x]);      swap(rt1[x],rt0[x]);swap(tag0[x],tag1[x]);      s[x]=r-l+1-s[x];la2[x]^=1;    }}il void Pushdown(re int x,re int l,re int r){  re int mid=l+r>>1;  if(la0[x]) cover(ls,l,mid,0),cover(rs,mid+1,r,0);  if(la1[x]) cover(ls,l,mid,1),cover(rs,mid+1,r,1);  if(la2[x]) cover(ls,l,mid,2),cover(rs,mid+1,r,2);  la0[x]=la1[x]=la2[x]=0;}il void Modify(re int x,re int l,re int r,re int ql,re int qr,re int op){  if(tag1[x]&&op==1) return;  if(tag0[x]&&op==0) return;  if(ql<=l&&r<=qr) return cover(x,l,r,op);  re int mid=l+r>>1;  Pushdown(x,l,r);  if(ql<=mid) Modify(ls,l,mid,ql,qr,op);  if(qr>mid) Modify(rs,mid+1,r,ql,qr,op);  upd(x);}il int Query(re int x,re int l,re int r,re int ql,re int qr){  if(ql<=l&&r<=qr) return s[x];  re int mid=l+r>>1;  Pushdown(x,l,r);  if(qr<=mid) return Query(ls,l,mid,ql,qr);  if(ql>mid) return Query(rs,mid+1,r,ql,qr);  return Query(ls,l,mid,ql,qr)+Query(rs,mid+1,r,ql,qr);}il dat QueryS(re int x,re int l,re int r,re int ql,re int qr){  if(ql<=l&&r<=qr) return (dat){t1[x],lt1[x],rt1[x],tag1[x]};  re int mid=l+r>>1;   Pushdown(x,l,r);  if(qr<=mid) return QueryS(ls,l,mid,ql,qr);  if(ql>mid) return QueryS(rs,mid+1,r,ql,qr);  re dat A=QueryS(ls,l,mid,ql,qr),B=QueryS(rs,mid+1,r,ql,qr);  A.t1=max(A.t1,B.t1);  A.t1=max(A.t1,A.rt1+B.lt1);  if(A.tag1) A.lt1=A.lt1+B.lt1;  if(B.tag1) A.rt1=A.rt1+B.rt1;else A.rt1=B.rt1;  A.t1=max(A.t1,max(A.lt1,A.rt1));  A.tag1=A.tag1&B.tag1;  return A;}int main(){  n=gi();m=gi();  Build(1,1,n);  re int gu=0;  while(m--)    {      re int op=gi(),l=gi()+1,r=gi()+1;        if(op<3) Modify(1,1,n,l,r,op);        if(op==3) printf("%d\n",Query(1,1,n,l,r));      if(op==4) printf("%d\n",QueryS(1,1,n,l,r).t1);    }  return 0;}

[SCOI2010]序列操作

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.