답안 #1042530

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1042530 2024-08-03T06:24:20 Z nightfal 식물 비교 (IOI20_plants) C++17
컴파일 오류
0 ms 0 KB
// #include "plants.h"
#include <iostream>
#include <cstdio>
#include <cassert>
#include <vector>
 
 
 
#include <utility>
#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].first += lz[node]; lz[node]=0;
    if (right < start or end < left) return {maxVal,m+1};
    if (left <= start and end <= right) return t[node];
 
    int mid=(start+end)/2;
    auto min1  = update(2*node,start,mid,left,right,diff);
    auto min2  = update(2*node+1,mid+1,end,left,right,diff);
    auto ans = min1<min2? min1:min2;
    t[node] = t[2*node]<t[2*node+1]? t[2*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].first += lz[node]; lz[node]=0;
    if (right < start or end < left) return {maxVal,m+1};
    if (left <= start and end <= right) return t[node];
    
    int mid=(start+end)/2;
    auto min1 = findMin(2*node,start,mid,left,right);
    auto min2 = findMin(2*node+1,mid+1,end,left,right);
    auto ans = min1<min2? min1:min2;
    t[node] = t[2*node]<t[2*node+1]? t[2*node]:t[2*node+1];    
    return ans;
}
void segInit(int node, int start, int end, std::vector<int> &r) {
    if (start==end) {t[node]={r[start],start}; return;}
    int mid=(start+end)/2;
    segInit(2*node,start,mid,r);
    segInit(2*node+1,mid+1,end,r);
    t[node] = t[2*node]<t[2*node+1]? t[2*node]:t[2*node+1];
    return;
}
int findPreMinI(int k,int minI1) {
    if (minI1>0) {
        auto[min2,minI2] = findMin(1,0,n-1,std::max(0,minI1-k+1),minI1-1);
        if (min2==0) minI1 = minI2;
    }
    if (minI1-k+1<0) {
        auto[min2,minI2] = findMin(1,0,n-1,minI1-k+1+n,n-1);
        if (min2==0) minI1 = minI2;
    }
    return minI1;
}
int computeRank(int minI1, int ranking) {
    // std::cout << "minI1: " << minI1 << "," << "ranking: " << ranking << std::endl;
 
    if (rank[minI1]!=n) return ranking;
    int minI2 = findPreMinI(k,minI1);
    // std::cout << "minI2: " << minI2 << std::endl;
 
    while (minI2 != minI1) {ranking = computeRank(minI2,ranking); minI2 = findPreMinI(k,minI1);}
    rank[minI1] = ranking--;
    // std::cout << "rank: "; print(rank);
    update(1,0,n-1,minI1,minI1,n-1);
    // std::cout << "t: "; 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 << "t: "; print(t);
    // std::cout << "lz: "; print(lz);
 
    return ranking;
}
void init4(int k, std::vector<int> &r) {
    int n = r.size(); 
    t.resize(4*n); lz.resize(4*n);
    segInit(1,0,n-1,r);
    rank.resize(n,n);
    int ranking = n-1;
    while (ranking >=0) {
        auto [min1,minI1] = findMin(1,0,n-1,0,n-1);
        ranking = computeRank(minI1,ranking);
    }
    return;
}
void init3(int k, std::vector<int> &r) {
    int n = r.size(); 
    t.resize(4*n); lz.resize(4*n);
    segInit(1,0,n-1,r);
    rank.resize(n);
    for(int i=n-1; i>=0; i--) {
        auto [min1,minI1] = findMin(1,0,n-1,0,n-1);
        int min2=1, minI2=minI1;
        int min3=1, minI3=minI1;
        if (minI1>0) std::tie(min2,minI2) = findMin(1,0,n-1,std::max(0,minI1-(n-k)),minI1-1);
        if (minI1-(n-k)<0) std::tie(min3,minI3) = findMin(1,0,n-1,minI1-(n-k)+n,n-1);
        if (min3==0) minI1=minI3;
        else if (min2==0) minI1=minI2;
        rank[minI1] = i;
        update(1,0,n-1,minI1,minI1,n-1);
        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);
    }
    return;
}
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;   
    // std::cout << "init2 rank: "; print(rank);
    return;
}
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;
}
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);
    else init4(k,r);
	return;
}
int compare_plants2(int x, int y) {
    if (rank[x]>rank[y]) return 1;
    else return -1;
}
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;
}
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_plants2(x,y);
    else return compare_plants2(x,y);
	return 0;
}

Compilation message

plants.cpp: In function 'int findPreMinI(int, int)':
plants.cpp:61:40: error: 'n' was not declared in this scope
   61 |         auto[min2,minI2] = findMin(1,0,n-1,std::max(0,minI1-k+1),minI1-1);
      |                                        ^
plants.cpp:65:40: error: 'n' was not declared in this scope
   65 |         auto[min2,minI2] = findMin(1,0,n-1,minI1-k+1+n,n-1);
      |                                        ^
plants.cpp: In function 'int computeRank(int, int)':
plants.cpp:73:22: error: 'n' was not declared in this scope
   73 |     if (rank[minI1]!=n) return ranking;
      |                      ^
plants.cpp:74:29: error: 'k' was not declared in this scope
   74 |     int minI2 = findPreMinI(k,minI1);
      |                             ^
plants.cpp:80:16: error: 'n' was not declared in this scope
   80 |     update(1,0,n-1,minI1,minI1,n-1);
      |                ^