[bzoj 1251]序列終結者
阿新 • • 發佈:2018-12-22
傳送門
Description
網上有許多題,就是給定一個序列,要你支援幾種操作:A、B、C、D。一看另一道題,又是一個序列 要支援幾種操作:D、C、B、A。尤其是我們這裡的某人,出模擬試題,居然還出了一道這樣的,真是沒技術含量……這樣 我也出一道題,我出這一道的目的是為了讓大家以後做這種題目有一個“庫”可以依靠,沒有什麼其他的意思。這道題目 就叫序列終結者吧。 【問題描述】 給定一個長度為N的序列,每個序列的元素是一個整數(廢話)。要支援以下三種操作: 1. 將[L,R]這個區間內的所有數加上V。 2. 將[L,R]這個區間翻轉,比如1 2 3 4變成4 3 2 1。 3. 求[L,R]這個區間中的最大值。 最開始所有元素都是0。
Solution
瘋狂水模板題……
還是wa了幾次,這次是因為build的時候左孩子(l,mid-1)
寫成了(l,mid)
我真的不行
Code
#include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f; } class FHQ { #define MN 50005 private: int ls[MN],rs[MN],add[MN],V[MN],ans[MN],pri[MN],siz[MN],sz; bool rev[MN]; inline unsigned int random() { static int x=23333; return x^=x<<13,x^=x>>17,x^=x<<5; } inline void up(int x) { siz[x]=siz[ls[x]]+siz[rs[x]]+1; ans[x]=V[x]; if(ls[x]) ans[x]=max(ans[x],ans[ls[x]]); if(rs[x]) ans[x]=max(ans[x],ans[rs[x]]); } inline void down(int x) { if(add[x]) { if(ls[x]) { ans[ls[x]]+=add[x];V[ls[x]]+=add[x]; add[ls[x]]+=add[x]; } if(rs[x]) { ans[rs[x]]+=add[x];V[rs[x]]+=add[x]; add[rs[x]]+=add[x]; } add[x]=0; } if(rev[x]) { std::swap(ls[x],rs[x]); if(ls[x]) rev[ls[x]]^=1; if(rs[x]) rev[rs[x]]^=1; rev[x]=0; } } public: int rt; int Merge(int rt1,int rt2) { if(rt1) down(rt1); if(rt2) down(rt2); if(!rt1||!rt2) return rt1|rt2; if(pri[rt1]<pri[rt2]) { rs[rt1]=Merge(rs[rt1],rt2); up(rt1);return rt1; } else { ls[rt2]=Merge(rt1,ls[rt2]); up(rt2);return rt2; } } void Split(int x,int k,int& rt1,int& rt2) { if(!x) return (void)(rt1=rt2=0); down(x); if(siz[ls[x]]>=k) { Split(ls[x],k,rt1,rt2); ls[x]=rt2,rt2=x,up(rt2); } else { Split(rs[x],k-siz[ls[x]]-1,rt1,rt2); rs[x]=rt1,rt1=x,up(rt1); } } void Build(int &x,int l,int r) { if(l>r) return; x=++sz;int mid=(l+r)>>1; V[x]=rev[x]=add[x]=ans[x]=0;pri[x]=random(); if(l==r) return(void)(siz[x]=1); Build(ls[x],l,mid-1);Build(rs[x],mid+1,r);up(x); } void Add(int l,int r,int c) { register int rt1,rt2,rt3,rt4; Split(rt,l-1,rt1,rt2);Split(rt2,r-l+1,rt3,rt4); add[rt3]+=c;V[rt3]+=c;ans[rt3]+=c;rt=Merge(rt1,Merge(rt3,rt4)); } void Reverse(int l,int r) { register int rt1,rt2,rt3,rt4; Split(rt,l-1,rt1,rt2);Split(rt2,r-l+1,rt3,rt4); rev[rt3]^=1;rt=Merge(rt1,Merge(rt3,rt4)); } void QueMax(int l,int r) { register int rt1,rt2,rt3,rt4; Split(rt,l-1,rt1,rt2);Split(rt2,r-l+1,rt3,rt4); printf("%d\n",ans[rt3]),rt=Merge(rt1,Merge(rt3,rt4)); } #undef MN }T; int main() { register int n,m,k,l,r; n=read();m=read(); T.Build(T.rt,1,n); while(m--) { k=read(),l=read(),r=read(); if(k==1) T.Add(l,r,read()); else if(k==2) T.Reverse(l,r); else if(k==3) T.QueMax(l,r); } return 0; }
Blog來自PaperCloud,未經允許,請勿轉載,TKS!