Skip to content

Instantly share code, notes, and snippets.

@Rockbet
Created May 16, 2019 02:10
Show Gist options
  • Save Rockbet/06c01490979701522b0777d779aada54 to your computer and use it in GitHub Desktop.
Save Rockbet/06c01490979701522b0777d779aada54 to your computer and use it in GitHub Desktop.
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+100;
int vet[maxn], resp[maxn], ind[maxn], pre[maxn], nex[maxn];
struct nod{
int v, d;
};
nod tree[4*maxn], lazy[4*maxn];
nod op(nod a, nod b){
if(a.v>b.v){
return a;
}
return b;
}
void build(int node, int l, int r){
if(l==r){
tree[node].v=vet[l];
tree[node].d=l;
lazy[node].v=-1;
return;
}
int mid = (l+r)>>1;
build(2*node,l,mid);
build(2*node+1,mid+1,r);
tree[node] = op(tree[2*node], tree[2*node+1]);
}
void flush(int node, int l, int r){
if(lazy[node].v==-1){
return;
}
tree[node].v = lazy[node].v;
if(l!=r){
lazy[2*node].v = lazy[node].v;
lazy[2*node+1].v = lazy[node].v;
}
lazy[node].v=0;
}
void update(int node, int tl, int tr, int l, int r, int val){
if(tl>r or l>tr)return;
flush(node,tl,tr);
if(tl>=l and tr<=r){
lazy[node].v=val;
flush(node,tl,tr);
return;
}
int mid = (tl+tr) >> 1;
update(2*node, tl, mid, l, r, val);
update(2*node+1, mid+1, tr, l, r, val);
tree[node] = op(tree[2*node], tree[2*node+1]);
}
nod query(int node, int tl, int tr, int l, int r){
if(tl>r or l>tr)return nod{0,0};
flush(node,tl,tr);
if(tl>=l and tr<=r)return tree[node];
int mid = (tl+tr) >> 1;
return op(query(2*node, tl, mid, l, r), query(2*node+1, mid+1, tr, l ,r));
}
int main(){
ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
int n, k;
cin >> n >> k;
for(int i=1; i<=n; i++){
cin >> vet[i];
ind[vet[i]]=i;
pre[i]=i-1;
nex[i]=i+1;
}
build(1, 1, n);
vector<int> fila;
int num=0;
for(int i=0; i<n;i++){
if(num==n)break;
nod s = query(1, 1, n, 1, n);
int atual = s.d;
int x = atual;
int y = atual;
if(i%2==0){
num++;
resp[atual]=1;
if(num==n)break;
for(int j=0; j<k; j++){
if(x>n)x=n;
while(resp[x]!=0 or x>n){
x=nex[x];
}
if(x>=1 and x<=n){
num++;
resp[x]=1;
}
if(num==n)break;
if(y<1)y=1;
while(resp[y]!=0 or y>n)y=pre[y];
if(y>=1 and y<=n){
num++;
resp[y]=1;
}
if(num==n)break;
}
int l = y, r = x;
if(l==0)l=1;
if(r==0)r=n;
pre[r+1]=l-1;
nex[l-1]=r+1;
update(1, 1, n, l, r, 0);
}
else{
num++;
resp[atual]=2;
if(num==n)break;
for(int j=0; j<k; j++){
if(x>n)x=n;
while(resp[x]!=0 or x>n)x=nex[x];
if(x>=1 and x<=n){
num++;
resp[x]=2;
}
if(num==n)break;
if(y<1)y=1;
while(resp[y]!=0 or y>n)y=pre[y];
if(y>=1 and y<=n){
num++;
resp[y]=2;
}
if(num==n)break;
}
int l = y, r = x;
if(l==0)l=1;
if(r==0)r=n;
pre[r+1]=l-1;
nex[l-1]=r+1;
update(1, 1, n, l, r, 0);
}
}
for(int i=1; i<=n; i++){
cout << resp[i];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment