Submission #956740

#TimeUsernameProblemLanguageResultExecution timeMemory
956740Trisanu_DasRadio Towers (IOI22_towers)C++17
60 / 100
1120 ms5584 KiB
#include "towers.h"
#include <bits/stdc++.h>
using namespace std;
#define forn(i,n) for(int i=0;i<n;++i)
 
struct minsgt {
    vector<int> t;
    int n, sz;
    int merge(int x, int y) {
      return min(x,y);
    }
    void build(int v, int l, int r) {
        if (r-l==1) return;
        int m=(l+r)>>1;
        build(2*v+1,l,m);
        build(2*v+2,m,r);
        t[v]=merge(t[2*v+1],t[2*v+2]);
    }
    minsgt(vector<int>&a) {
        n=a.size();
        sz=1;
        while (sz<n) sz<<=1;
        t.assign(2*sz-1,1e9+7);
        forn(i,n) t[sz-1+i]=a[i];
        build(0,0,sz);
    }
    int query(int v, int l, int r, int lx, int rx) {
        if (r<=lx || l>=rx) return 1e9+7;
        if (lx<=l && r<=rx) return t[v];
        int m=(l+r)>>1;
        int L=query(2*v+1,l,m,lx,rx);
        int R=query(2*v+2,m,r,lx,rx);
        return merge(L,R);
    }
    int query(int l, int r) {
        return query(0,0,sz,l,r);
    }
};
 
struct maxsgt {
    vector<int> t;
    int n, sz;
    int merge(int x, int y) {
      return max(x,y);
    }
    void build(int v, int l, int r) {
        if (r-l==1) return;
        int m=(l+r)>>1;
        build(2*v+1,l,m);
        build(2*v+2,m,r);
        t[v]=merge(t[2*v+1],t[2*v+2]);
    }
    maxsgt(vector<int>&a) {
        n=a.size();
        sz=1;
        while (sz<n) sz<<=1;
        t.assign(2*sz-1,0);
        forn(i,n) t[sz-1+i]=a[i];
        build(0,0,sz);
    }
    int query(int v, int l, int r, int lx, int rx) {
        if (r<=lx || l>=rx) return 0;
        if (lx<=l && r<=rx) return t[v];
        int m=(l+r)>>1;
        int L=query(2*v+1,l,m,lx,rx);
        int R=query(2*v+2,m,r,lx,rx);
        return merge(L,R);
    }
    int query(int l, int r) {
        return query(0,0,sz,l,r);
    }
};
 
int n;
vector<int> h;
int paiu=1;
int pos=0,mx;
int D=-1;
int Q=0;
vector<int> pr(1e5+3,0);
void init(int N, vector<int> H) {
  n=N, h=H;
  forn(i,n) {
    if (h[i]>h[pos]) {
      pos=i;
    }
  }
  mx=h[pos];
  for(int i=pos-1; i+1; --i) paiu&=h[i+1]>h[i];
  for(int i=pos+1; i<n; ++i) paiu&=h[i-1]>h[i];
 
}
 
minsgt minst(pr);
maxsgt maxst(pr);
vector<int> nxt(1e5+3,0);
vector<int> jump(1e5+3,0);
int sq;
void build() {
 
  minst = minsgt(h);
  maxst = maxsgt(h);
  vector<int> less(n+1,n);
  forn(i,n) {
    int l=i, r=n;
    while (l<r) {
      int m=(l+r)>>1;
      int x=minst.query(i,m+1);
      if (h[i]-x>=D) r=m;
      else l=m+1;
    }
    less[i]=r;
  }
  for (int i=n-2; i+1; --i) less[i]=min(less[i],less[i+1]);
  vector<int> greater(n+1,n);
  forn(i,n) {
    int l=i, r=n;
    while (l<r) {
      int m=(l+r)>>1;
      int x=maxst.query(i,m+1);
      if (x-h[i]>=D) r=m;
      else l=m+1;
    }
    greater[i]=r;
  }
  for (int i=n-2; i+1; --i) {
    greater[i]=min(greater[i],greater[i+1]);
  }
  for (int i=n-1; i+1; --i) {
    nxt[i]=less[greater[i]];
  }
 
  sq = sqrt(n);
  for (int i=0; i<n; ++i) {
    int p=i;
    for (int cnt=0; cnt<sq; ++cnt) {
      if (p>=n) {
        break;
      }
      p=nxt[p];
    }
    jump[i]=p;
  }
  nxt[n]=jump[n]=n;
}
 
int max_towers(int l, int r, int d) {
 
  if (paiu) {
    if (r<=pos || l>=pos) return 1;
    int L=h[l], R=h[r];
    return 1+(max(L,R) <= mx-d);
  }
 
  if (D==-1) {
    D=d;
    build();
  }
  int ans=0;
  int i=l;
  while (jump[i+1]<=r) {
    i=jump[i];
    ans+=sq;
  }
  while (i<=r) {
    i=nxt[i];
    ans++;
  } 
  return max(ans,1);
 
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...