Submission #477634

#TimeUsernameProblemLanguageResultExecution timeMemory
477634RGBBStreet Lamps (APIO19_street_lamps)C++14
100 / 100
2795 ms120200 KiB
#include <iostream> #include <bits/stdc++.h> using namespace std; typedef pair<int,int>pi; const int MAX=3*1e5; //input int n,q,state[MAX],inp[MAX][2]; bool type[MAX];//true is toggle, false is query string s; //first sweep int beg[MAX]; map<int,int>lines; vector<pi>add[MAX],sub[MAX];//location, value void firstSweep(){ int orig=0; for(int i=0;i<n;i++){ if(state[i]==1){ if(i!=0&&state[i-1]==1)lines[orig]++; else{ lines[i]=i; orig=i; } } else beg[i]=i-1; } for(auto&[i,j]:lines)for(int k=i;k<=j;k++)beg[k]=j; for(int i=0;i<q-1;i++){ if(!type[i])continue; int cur=inp[i][0]; if(state[cur]==1){ state[cur]=0; pi cl=*prev(lines.upper_bound(cur)); lines.erase(lines.find(cl.first)); if(cur!=cl.first)lines[cl.first]=cur-1; if(cur!=cl.second)lines[cur+1]=cl.second; add[cl.first].push_back({i+1,cur-1}); sub[cur].push_back({i+1,cur-1}); } else{ state[cur]=1; int lef=cur; int rig=cur; if(lines.find(cur+1)!=lines.end()){ rig=lines[cur+1]; lines.erase(lines.find(cur+1)); } if(lines.upper_bound(cur)!=lines.begin()){ pi cl=*prev(lines.upper_bound(cur)); if(cl.second==cur-1){ lef=cl.first; lines.erase(lines.find(cl.first)); } } lines[lef]=rig; add[lef].push_back({i+1,rig}); sub[cur].push_back({i+1,rig}); } } } //second sweep struct sparseBIT{ vector<pi>todo; int cnt[MAX+1],st[MAX+1]; vector<int>val,bit; void init(){ int lst[MAX+1]; for(int i=0;i<=MAX;i++)lst[i]=cnt[i]=0; sort(todo.begin(),todo.end(),[](const pi&a,const pi&b){return a.second<b.second;}); for(pi t:todo){ for(int x=t.first;x<=MAX;x+=x&-x){ if(lst[x]!=t.second){ lst[x]=t.second; cnt[x]++; } } } int sum=0; for(int i=0;i<=MAX;i++){ lst[i]=0; st[i]=sum; sum+=cnt[i]; } val.resize(sum); bit.resize(sum); for(pi t:todo){ for(int x=t.first;x<=MAX;x+=x&-x){ if(lst[x]!=t.second){ lst[x]=t.second; val[st[x]++]=t.second; } } } } void push(int x,int y){ if(x<0||x>=MAX||y<0||y>=MAX)return; todo.push_back({x+1,y+1}); } int rank(int y,int l,int r){return upper_bound(begin(val)+l,begin(val)+r,y)-begin(val)-l;} void UPDATE(int x,int y,int t){ int z=st[x]-cnt[x]; for(y=rank(y,z,st[x]);y<=cnt[x];y+=y&-y)bit[z+y-1]+=t; } void update(int x,int y,int t){ if(x<0||x>=MAX||y<0||y>=MAX)return; x++; y++; for(;x<=MAX;x+=x&-x)UPDATE(x,y,t); } int QUERY(int x,int y){ int ret=0; int z=st[x]-cnt[x]; for(y=rank(y,z,st[x]);y;y-=y&-y)ret+=bit[z+y-1]; return ret; } int query(int x,int y){ if(x<0||x>=MAX||y<0||y>=MAX)return 0; x++; y++; int ret=0; for(;x;x-=x&-x)ret+=QUERY(x,y); return ret; } }; int val[MAX],outp[MAX]; vector<pi>query[MAX]; set<int>nei; sparseBIT bit; void processInsert(int p,int v){ nei.insert(p); val[p]=v; int nxt=*next(nei.find(p)); bit.update(p,MAX-1-v,nxt-p); if(p!=0){ int prv=*prev(nei.find(p)); bit.update(prv,MAX-1-val[prv],p-nxt); } } void processDelete(int p,int v){ int nxt=*next(nei.find(p)); bit.update(p,MAX-1-v,p-nxt); if(p!=0){ int prv=*prev(nei.find(p)); bit.update(prv,MAX-1-val[prv],nxt-p); } nei.erase(nei.find(p)); } int processQuery(int p,int v){ int prv=*prev(nei.upper_bound(p)); int ret=bit.query(prv-1,MAX-1-v); if(val[prv]>=v)ret+=p-prv+1; return ret; } void secondSweep(){ nei.insert(q); for(int i=0;i<n;i++)bit.push(0,MAX-1-beg[i]); for(int i=0;i<n;i++)for(pi j:add[i])bit.push(j.first,MAX-1-j.second); bit.init(); for(int i=0;i<n;i++){ processInsert(0,beg[i]); for(pi j:add[i])processInsert(j.first,j.second); for(pi j:query[i])outp[j.first]=processQuery(j.first,j.second); for(pi j:sub[i])processDelete(j.first,j.second); processDelete(0,beg[i]); } } //driver int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cin>>n>>q>>s; for(int i=0;i<n;i++)state[i]=s[i]-'0'; for(int i=0;i<q;i++){ string op; cin>>op; if(op=="toggle"){ type[i]=true; cin>>inp[i][0]; inp[i][0]--; } else{ type[i]=false; cin>>inp[i][0]>>inp[i][1]; inp[i][0]--; inp[i][1]-=2; } } firstSweep(); for(int i=0;i<q;i++)if(!type[i])query[inp[i][0]].push_back({i,inp[i][1]}); secondSweep(); for(int i=0;i<q;i++)if(!type[i])cout<<outp[i]<<"\n"; }

Compilation message (stderr)

street_lamps.cpp: In function 'void firstSweep()':
street_lamps.cpp:26:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   26 |     for(auto&[i,j]:lines)for(int k=i;k<=j;k++)beg[k]=j;
      |              ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...