Submission #1042381

#TimeUsernameProblemLanguageResultExecution timeMemory
1042381nightfalComparing Plants (IOI20_plants)C++17
32 / 100
339 ms18260 KiB
#include "plants.h" #include <iostream> #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].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, std::vector<int> &r) { if (start==end) {t[node]={start,r[start]}; return;} int mid=(start+end)/2; segInit(2*node,start,mid,r); segInit(2*node+1,mid+1,end,r); 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,r); // 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 (stderr)

plants.cpp: In function 'std::pair<int, int> update(int, int, int, int, int, int)':
plants.cpp:33:33: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   33 |     if (min1<min2 or min1==min2 and minI1 < minI2) ans = {minI1,min1};
      |                      ~~~~~~~~~~~^~~~~~~~~~~~~~~~~
plants.cpp:38:33: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   38 |     if (min1<min2 or min1==min2 and minI1 < minI2) t[node] = t[2*node];
      |                      ~~~~~~~~~~~^~~~~~~~~~~~~~~~~
plants.cpp: In function 'std::pair<int, int> findMin(int, int, int, int, int)':
plants.cpp:55:33: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   55 |     if (min1<min2 or min1==min2 and minI1 < minI2) ans = {minI1,min1};
      |                      ~~~~~~~~~~~^~~~~~~~~~~~~~~~~
plants.cpp:60:33: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   60 |     if (min1<min2 or min1==min2 and minI1 < minI2) t[node] = t[2*node];
      |                      ~~~~~~~~~~~^~~~~~~~~~~~~~~~~
plants.cpp: In function 'void segInit(int, int, int, std::vector<int>&)':
plants.cpp:71:39: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   71 |     t[node] = min1<min2 or min1==min2 and minI1<minI2? t[2*node]:t[2*node+1];
      |                            ~~~~~~~~~~~^~~~~~~~~~~~~~~
plants.cpp: In function 'void init1(int, std::vector<int>&)':
plants.cpp:140:37: warning: 'decVal' may be used uninitialized in this function [-Wmaybe-uninitialized]
  140 |         inc[s%n] = incVal; dec[s%n] = decVal;
plants.cpp:140:18: warning: 'incVal' may be used uninitialized in this function [-Wmaybe-uninitialized]
  140 |         inc[s%n] = incVal; dec[s%n] = decVal;
#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...