제출 #633372

#제출 시각아이디문제언어결과실행 시간메모리
633372codr0ZIGZAG (INOI20_zigzag)C++14
0 / 100
2084 ms45376 KiB
// Code by Parsa Eslami #include <bits/stdc++.h> #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define FOR(i,a,b) for(int i=a;i<=b;i++) #define FORR(i,a,b) for(int i=a;i>=b;i--) #define maxm(a,b) a=max(a,b) #define minm(a,b) a=min(a,b) #define bit(i,j) ((j>>i)&1) #define F first #define S second #define dmid int mid=(r+l)/2 #define lc 2*id #define rc 2*id+1 #define err(x) cerr<<#x<<"="<<x<<'\n' #define pb push_back #define SZ(x) (int)x.size() #define all(x) x.begin(),x.end() using namespace std; const int N=3e5+4; struct node{ int l,r,sz; ll ans; }; node sg[4*N],emp; pll seg[4*N]; bool B[N]; ll b[N]; int n; struct fenwick{ int fen[N]; void upd(int k,int x){ while(k<N){ fen[k]+=x; k+=(k&(-k)); } } int get(int k){ int rt=0; while(k>0){ rt+=fen[k]; k-=(k&(-k)); } return rt; } }; fenwick fen; void build(int id,int l,int r){ seg[id].F=+1; if(l+1==r){ seg[id].S=b[l]; return; } dmid; build(lc,l,mid); build(rc,mid,r); } void shift(int id){ seg[id].S*=seg[id].F; seg[lc].S+=seg[id].S*seg[lc].F; seg[rc].S+=seg[id].S*seg[rc].F; seg[lc].F*=seg[id].F; seg[rc].F*=seg[id].F; seg[id]={+1,0}; } void upd(int id,int l,int r,int st,int en,ll x){ FOR(i,st,en-1) b[i]+=x; return; if(st>=r||en<=l) return; if(st<=l&&en>=r){ seg[id].S+=x*seg[id].F; return; } shift(id); dmid; upd(lc,l,mid,st,en,x); upd(rc,mid,r,st,en,x); } void upd(int id,int l,int r,int st,int en){ FOR(i,st,en-1) b[i]*=-1; return; if(st>=r||en<=l) return; if(st<=l&&en>=r){ seg[id].F*=-1; return; } shift(id); dmid; upd(lc,l,mid,st,en); upd(rc,mid,r,st,en); } ll get(int id,int l,int r,int x){ return b[x]; if(x<l||x>=r) return 0; if(l+1==r) return seg[id].F*seg[id].S; shift(id); dmid; return (get(lc,l,mid,x)+get(rc,mid,r,x)); } node MERGE(node L,node R){ node rt; if(L.sz==0) return R; if(R.sz==0) return L; if(L.l==L.sz) rt.l=L.sz+R.l; else rt.l=L.l; if(R.r==R.sz) rt.r=L.r+R.sz; else rt.r=R.r; rt.sz=L.sz+R.sz; rt.ans=L.ans+R.ans+1LL*L.r*R.l; return rt; } void BUILD(int id,int l,int r){ sg[id].sz=r-l; if(l+1==r) return; dmid; BUILD(lc,l,mid); BUILD(rc,mid,r); } void UPD(int id,int l,int r,int ind,bool v){ if(ind<l||ind>=r) return; if(l+1==r){ sg[id].ans=sg[id].r=sg[id].l=v; return; } dmid; UPD(lc,l,mid,ind,v); UPD(rc,mid,r,ind,v); sg[id]=MERGE(sg[lc],sg[rc]); } node GET(int id,int l,int r,int st,int en){ if(st>=r||en<=l) return emp; if(st<=l&&en>=r) return sg[id]; dmid; return MERGE(GET(lc,l,mid,st,en),GET(rc,mid,r,st,en)); } bool check(int i){ if(i<2||i>n-1) return 0; int A=get(1,1,n+1,i-1); int BB=get(1,1,n+1,i); int C=get(1,1,n+1,i+1); if(A!=BB&&BB!=C&&((A<BB)^(BB<C))) return 1; else return 0; } int32_t main(){ iostream::sync_with_stdio(0); cin.tie(0); int q; cin>>n>>q; FOR(i,1,n) cin>>b[i]; build(1,1,n+1); BUILD(1,1,n+1); FOR(i,1,n) UPD(1,1,n+1,i,check(i)); FOR(i,2,n){ B[i]=(b[i]==b[i-1]); fen.upd(i,B[i]); } while(q--){ char id; int l,r; cin>>id>>l>>r; if(id=='?'){ ll K=2*(r-l+1)-1-fen.get(r)+fen.get(l); if((r-l+1)>2) K+=GET(1,1,n+1,l+1,r).ans; cout<<K<<'\n'; }else if(id=='*') upd(1,1,n+1,l,r+1); else{ int x; cin>>x; upd(1,1,n+1,l,r+1,x); } vector<int> ch={l-1,l,r,r+1}; for(int v:ch) if(v>=1&&v<=n) UPD(1,1,n+1,v,check(v)); if(l>1) fen.upd(l,(get(1,1,n+1,l)==get(1,1,n+1,l-1))-B[l]); if(r<n) fen.upd(r+1,(get(1,1,n+1,r+1)==get(1,1,n+1,r))-B[r+1]); B[l]=(get(1,1,n+1,l)==get(1,1,n+1,l-1)); B[r+1]=(get(1,1,n+1,r+1)==get(1,1,n+1,r)); /* FOR(i,1,n) cout<<get(1,1,n+1,i)<<" "; cout<<'\n'; FOR(i,1,n) cout<<GET(1,1,n+1,i,i+1).ans<<" "; cout<<'\n';*/ } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...