#include "plants.h"
#include <iostream>
#include <pair>
#include <tuple>
// using namespace std;
#define maxVal 1'000'000'001
static std:: vector<int> inc,dec,rank,lz;
static std:: vector<std::pair<int,int>> t;
static int l,m;
// void print(std::vector<int> &v) {for(int elem: v) std::cout << elem << " "; std::cout << std::endl;}
void print(std::vector<int> &v) {for(int elem: v) std::cout << elem << " "; std::cout << std::endl;};
void print(std::vector<std::pair<int,int>> &v) {
for(auto [a,b]: v)
std::cout << "(" << a << "," << b << ") ";
std::cout << std::endl;
return;
}
std::pair<int,int> update(int node,int start,int end,int left,int right,int diff) {
if (left <= start and end <= right) lz[node] += diff;
if (start!=end) {lz[2*node] += lz[node]; lz[2*node+1] += lz[node];}
t[node].second += lz[node]; lz[node]=0;
if (right < start or end < left) return {m+1,maxVal};
if (left <= start and end <= right) return t[node];
int mid=(start+end)/2;
int minI1,minI2,min1,min2;
std::pair<int,int> ans;
std::tie(minI1,min1) = update(2*node,start,mid,left,right,diff);
std::tie(minI2,min2) = update(2*node+1,mid+1,end,left,right,diff);
if (min1<min2 or min1==min2 and minI1 < minI2) ans = {minI1,min1};
else ans = {minI2,min2};
std::tie(minI1,min1) = t[2*node];
std::tie(minI2,min2) = t[2*node+1];
if (min1<min2 or min1==min2 and minI1 < minI2) t[node] = t[2*node];
else t[node] = t[2*node+1];
return ans;
}
std::pair<int,int> findMin(int node, int start, int end, int left, int right) {
if (start!=end) {lz[2*node] += lz[node]; lz[2*node+1] += lz[node];}
t[node].second += lz[node]; lz[node]=0;
if (right < start or end < left) return {m+1,maxVal};
if (left <= start and end <= right) return t[node];
int mid=(start+end)/2;
int minI1,minI2,min1,min2;
std::pair<int,int> ans;
std::tie(minI1,min1) = findMin(2*node,start,mid,left,right);
std::tie(minI2,min2) = findMin(2*node+1,mid+1,end,left,right);
if (min1<min2 or min1==min2 and minI1 < minI2) ans = {minI1,min1};
else ans = {minI2,min2};
std::tie(minI1,min1) = t[2*node];
std::tie(minI2,min2) = t[2*node+1];
if (min1<min2 or min1==min2 and minI1 < minI2) t[node] = t[2*node];
else t[node] = t[2*node+1];
return ans;
}
void segInit(int node, int start, int end) {
if (start==end) {t[node]={start,r[start]}; return;}
int mid=(start+end)/2;
segInit(2*node,start,mid);
segInit(2*node+1,mid+1,end);
auto [minI1,min1] = t[2*node];
auto [minI2,min2] = t[2*node+1];
t[node] = min1<min2 or min1==min2 and minI1<minI2? t[2*node]:t[2*node+1];
return;
}
void init3(int k, std::vector<int> r) {
int n = r.size();
//r.push_back(maxVal);
t.resize(4*n); lz.resize(4*n);
segInit(1,0,n-1);
// print(r); print(t);
rank.resize(n);
for(int i=n-1; i>=0; i--) {
auto [minI1,min1] = findMin(1,0,n-1,0,n-1);
// std::cout << "minI1: " << minI1 << std::endl;
// std:: cout << "t" << std::endl; print(t);
int minI2=minI1,min2=1;
int minI3=minI1,min3=1;
if (minI1>0) std::tie(minI2,min2) = findMin(1,0,n-1,std::max(0,minI1-(n-k)),minI1-1);
if (minI1-(n-k)<0) std::tie(minI3,min3) = findMin(1,0,n-1,minI1-(n-k)+n,n-1);
if (min3==0) minI1=minI3;
else if (min2==0) minI1=minI2;
// std::cout << "minI1: " << minI1 << std::endl;
// print(t);
rank[minI1] = i;
// std::cout << "rank: "; print(rank);
update(1,0,n-1,minI1,minI1,n-1);
// std::cout << "t" << std::endl; print(t);
update(1,0,n-1,std::max(0,minI1-k+1),minI1-1,-1);
if (minI1-k+1<0) update(1,0,n-1,minI1-k+1+n,n-1,-1);
// std::cout << "minI1-k+1: " << minI1-k+1 << std::endl;
// std::cout << "t" << std::endl; print(t);
// std::cout << "lz" << std::endl; print(lz);
}
return;
}
int compare_plants3(int x, int y) {
if (rank[x]>rank[y]) return 1;
else return -1;
}
int findMax(int k, std::vector<int> &r) {
int i=2*m-1;
while (r[i%m]!=0) {i--;}
int j = i-1;
while (j > i-k) {
if (r[j%m]==0) i = j;
j--;
}
for(int j=i; j>i-k; j--) r[j%m]--;
return i%m;
}
void init2(int k, std::vector<int> r) {
int n = r.size();
rank.resize(n);
for(int i=n-1; i>=0; i--) {
rank[findMax(k,r)] = i;
}
return;
}
int compare_plants2(int x, int y) {
if (rank[x]>rank[y]) return 1;
else return -1;
}
void init1(int k, std::vector<int> r) {
int n = r.size();
inc.resize(n); dec.resize(n);
for(int i=0; i<n; i++) {inc[i] = dec[i] = i;}
int s,incVal,decVal;
for(s=2*n-1; s>=0; s--) {
if (r[s%n]==0) incVal = s;
else decVal = s;
inc[s%n] = incVal; dec[s%n] = decVal;
}
return;
}
int compare_plants1(int x, int y) {
if (y <= dec[x] or x+m <= inc[y]) return 1;
else if (y <= inc[x] or x+m <= dec[y]) return -1;
return 0;
}
void init(int k, std::vector<int> r) {
int n = r.size();
m=n; l=k;
if(k==2) init1(k, r);
else if(n<=5000 and 2*k>n) init2(k, r);
else if(2*k>n) init3(k,r);
return;
}
int compare_plants(int x, int y) {
if(l==2) return compare_plants1(x,y);
else if(m<=5000 and 2*l>m) return compare_plants2(x,y);
else if(2*l>m) return compare_plants3(x,y);
return 0;
}
Compilation message
plants.cpp:3:10: fatal error: pair: No such file or directory
3 | #include <pair>
| ^~~~~~
compilation terminated.