Submission #428964

#TimeUsernameProblemLanguageResultExecution timeMemory
428964alishahali1382Comparing Plants (IOI20_plants)C++14
15 / 100
1968 ms58508 KiB
#include "plants.h"
#include <bits/stdc++.h>
#pragma GCC optimize("O2")
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
#define debug(x) {cerr<<#x<<"="<<x<<"\n";}
#define debug2(x, y) {cerr<<"{"<<#x<<", "<<#y<<"}={"<<x<<", "<<y<<"}\n";}
#define debugp(p) {cerr<<#p<<"={"<<p.first<<", "<<p.second<<"}\n";}
#define debugv(abcd) {cerr<<#abcd<<": "; for (auto dcba:abcd) cerr<<dcba<<", ";cerr<<"\n";}
#define pb push_back
#define all(x) x.begin(), x.end()
#define SZ(x) ((int)x.size())

const int inf=1000000100; // 1e9
const ll INF=10000000001000000; // 1e16
const int mod=1000000007;
const int MAXN=200010, LOG=20;

int n, m, k, x, y, u, v, t, a, b, ans;
int A[MAXN], B[MAXN];
int mark1[MAXN], mark2[MAXN];
vector<int> G[MAXN], GR[MAXN];

struct Segment{
	pii seg[MAXN<<2];
	int lazy[MAXN<<2];
	pii Build(int id, int tl, int tr, int *A){
		if (tr-tl==1) return seg[id]={A[tl], tl};
		int mid=(tl+tr)>>1;
		return seg[id]=min(Build(id<<1, tl, mid, A), Build(id<<1 | 1, mid, tr, A));
	}
	inline void add_lazy(int id, int val){
		seg[id].first+=val;
		lazy[id]+=val;
	}
	inline void shift(int id){
		if (lazy[id]){
			add_lazy(id<<1, lazy[id]);
			add_lazy(id<<1 | 1, lazy[id]);
			lazy[id]=0;
		}
	}
	void Add(int id, int tl, int tr, int l, int r, int val){
		if (r<=tl || tr<=l) return ;
		if (l<=tl && tr<=r){
			add_lazy(id, val);
			return ;
		}
		shift(id);
		int mid=(tl+tr)>>1;
		Add(id<<1, tl, mid, l, r, val);
		Add(id<<1 | 1, mid, tr, l, r, val);
		seg[id]=min(seg[id<<1], seg[id<<1 | 1]);
	}
	pii Get(int id, int tl, int tr, int l, int r){
		if (r<=tl || tr<=l) return {inf, 0};
		if (l<=tl && tr<=r) return seg[id];
		shift(id);
		int mid=(tl+tr)>>1;
		return min(Get(id<<1, tl, mid, l, r), Get(id<<1 | 1, mid, tr, l, r));
	}
} seg1, seg2, seg3;

void relax(){
	while (!seg1.seg[1].first){
		int mx=seg1.seg[1].second;
		// cerr<<mx<<" became 0\n";
		seg1.Add(1, 0, n, mx, mx+1, inf);
		seg2.Add(1, 0, n, mx, mx+1, -inf);
		seg2.Add(1, 0, n, mx+1, mx+k, +1);
		seg2.Add(1, 0, n, 0, mx+k-n, +1);
	}
}

inline void add_edge(int u, int v){
	G[u].pb(v);
	GR[v].pb(u);
}
void dfs1(int node){
	mark1[node]=1;
	for (int v:G[node]) if (!mark1[v]) dfs1(v);
}
void dfs2(int node){
	mark2[node]=1;
	for (int v:GR[node]) if (!mark2[v]) dfs2(v);
}

void init(int _k, vi _A){
	n=SZ(_A);
	k=_k;
	for (int i=0; i<n; i++) A[i]=_A[i];
	seg1.Build(1, 0, n, A);
	seg2.Build(1, 0, n, B); // any empty array
	seg3.Build(1, 0, n, B);
	seg2.Add(1, 0, n, 0, n, inf);
	seg3.Add(1, 0, n, 0, n, inf);
	relax();
	for (int i=0; i<n; i++){
		int mx=seg2.seg[1].second;
		B[mx]=n-i;
		// debug(mx)
		
		seg2.Add(1, 0, n, mx, mx+1, inf);
		seg2.Add(1, 0, n, mx+1, mx+k, -1);
		seg2.Add(1, 0, n, 0, mx+k-n, -1);
		
		seg1.Add(1, 0, n, mx-k+1, mx, -1);
		seg1.Add(1, 0, n, n+mx-k+1, n, -1);
		relax();



		seg3.Add(1, 0, n, mx, mx+1, -inf+B[mx]);
		pii l=min(seg3.Get(1, 0, n, mx-k+1, mx), seg3.Get(1, 0, n, mx-k+1+n, n));
		pii r=min(seg3.Get(1, 0, n, mx+1, mx+k), seg3.Get(1, 0, n, 0, mx+k-n));
		// debug(i)
		// debugp(l)
		// debugp(r)
		// cerr<<"\n";
		if (l.first<inf) add_edge(mx, l.second);
		if (r.first<inf) add_edge(mx, r.second);

	}
	// for (int i=0; i<n; i++) cerr<<B[i]-1<<" \n"[i==n-1];
	dfs1(0);
	dfs2(0);

	return;
}

int compare_plants(int x, int y){
	if (mark1[y]) return -1;
	if (mark2[y]) return +1;
	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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...