# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
321620 | gmyu | trapezoid (balkan11_trapezoid) | C++14 | 260 ms | 17744 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/*
ID: USACO_template
LANG: C++
PROG: USACO
*/
#include <iostream> //cin , cout
#include <fstream> //fin, fout
#include <stdio.h> // scanf , pringf
#include <cstdio>
#include <algorithm> // sort , stuff
#include <stack> // stacks
#include <queue> // queues
#include <map>
#include <string>
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi; /// adjlist without weight
typedef vector<pii> vii; /// adjlist with weight
typedef vector<pair<int,pii>> vpip; /// edge with weight
typedef long long ll;
#define mp make_pair
#define fst first
#define snd second
#define pb push_back
#define trav(u, adj_v) for (auto& u: adj_v)
const int MOD = 30013; // 998244353;
const int MX = 2e5+5; //
const ll INF = 1e18; //
#define MAXV 100007
#define MAXE 100007
const int xdir[4] = {1,0,-1,0}, ydir[4] = {0,1,0,-1}; /// 4 directions
struct NODE {
int x, y;
int val;
int visited;
};
struct EDGE {
int from, to;
ll weight;
bool operator<(EDGE other) const { return weight < other.weight; }
};
/// code from USACO examples
void setIO(string name) {
ios_base::sync_with_stdio(0); cin.tie(0);
freopen((name+".in").c_str(),"r",stdin);
freopen((name+".out").c_str(),"w",stdout);
}
bool debug = false, submit = true;
int N;
struct TRA {
ll x[2][2];
};
TRA traList[MAXV];
vector<ll> uniqX[2];
bool compFunc(const TRA& v1, const TRA& v2) {
if(v1.x[0][0] != v2.x[0][0])
return v1.x[0][0] < v2.x[0][0];
else if(v1.x[0][1] != v2.x[0][1])
return v1.x[0][1] < v2.x[0][1];
else if(v1.x[1][0] != v2.x[1][0])
return v1.x[1][0] < v2.x[1][0];
else
return v1.x[1][1] < v2.x[1][1];
}
int dp[MAXV][2]; /// max and its rep counts, if the i-th tra is used to form the set
/// ------ Segment Treee --------
int Nseg[2][2];
struct SEGNODE {
int val_m, val_mc;
SEGNODE operator+(SEGNODE b) { /// seg operations
SEGNODE ret;
if(val_m == b.val_m) {
ret.val_m = val_m;
ret.val_mc = (val_mc + b.val_mc) % MOD;
} else {
ret.val_m = max(val_m, b.val_m);
ret.val_mc = (val_m > b.val_m) ? val_mc : b.val_mc;
}
return ret;
}
};
SEGNODE seg[2][600007]; /// max 2e5 unique y, which needs 2^19 for Nseg
void buildSeg(int ln, int v = 1, int l = Nseg[0][0], int r = Nseg[0][1]) {
if(l == r) { // leaf
seg[ln][v] = (SEGNODE) {0, 0};
return;
}
int mid = (l + r) / 2;
buildSeg(ln, 2*v, l, mid); buildSeg(ln, 2*v+1, mid+1, r);
seg[ln][v] = seg[ln][2*v] + seg[ln][2*v+1];
}
void initSeg() {
/// build a segment tree for array of interest indexed from Nseg[0] to Nseg[1]
Nseg[0][0] = 0; Nseg[0][1] = uniqX[0].size();
Nseg[1][0] = 0; Nseg[1][1] = uniqX[1].size();
buildSeg(0,1,Nseg[0][0], Nseg[0][1]);
buildSeg(1,1,Nseg[1][0], Nseg[1][1]);
}
SEGNODE querySeg(int ln, ll qle, ll qri, int v = 1, int l = Nseg[0][0], int r = Nseg[0][1]) {
if(uniqX[ln][r] < qle || uniqX[ln][l] > qri) return {0, 0};
if(qle <= uniqX[ln][l] && uniqX[ln][r] <= qri) return seg[ln][v];
int mid = (l + r) / 2;
return querySeg(ln, qle, qri, 2*v, l, mid) + querySeg(ln, qle, qri, 2*v+1, mid+1, r);
}
void updateSeg(int ln, ll vtx, int v1, int v2, int v = 1, int l = Nseg[0][0], int r = Nseg[0][1]){
if(l == r) { // leaf
seg[ln][v] = (SEGNODE) {v1, v2}; /// dp of max and # of max
return;
}
int mid = (l + r) / 2;
(vtx <= uniqX[ln][mid]) ? updateSeg(ln, vtx, v1, v2, 2*v, l, mid) : updateSeg(ln, vtx, v1, v2, 2*v+1, mid+1, r);
seg[ln][v] = seg[ln][2*v] + seg[ln][2*v+1];
}
int main() {
debug = false; submit = false;
if(submit) setIO("testName");
int i, j, k;
int ans = 0;
cin >> N ;
for(i=1; i<=N; i++) {
cin >> traList[i].x[0][0] >> traList[i].x[0][1] >> traList[i].x[1][0] >> traList[i].x[1][1];
uniqX[0].pb(traList[i].x[0][0]); uniqX[0].pb(traList[i].x[0][1]);
uniqX[1].pb(traList[i].x[1][0]); uniqX[1].pb(traList[i].x[1][1]);
}
traList[0] = {0,0,0,0}; traList[N+1] = {INF, INF, INF, INF};
uniqX[0].pb(0); uniqX[0].pb(INF); uniqX[1].pb(0); uniqX[1].pb(INF);
sort(uniqX[0].begin(), uniqX[0].end()); // uniqX[0].erase(unique(uniqX[0].begin(), uniqX[0].end()), uniqX[0].end());
sort(uniqX[1].begin(), uniqX[1].end()); // uniqX[0].erase(unique(uniqX[0].begin(), uniqX[0].end()), uniqX[0].end());
sort(traList, traList+N+2, compFunc);
dp[0][0] = 0; dp[0][1] = 0;
initSeg();
updateSeg(0, 0, 0, 1, 1, Nseg[0][0], Nseg[0][1]);
updateSeg(1, 0, 0, 1, 1, Nseg[1][0], Nseg[1][1]);
SEGNODE ans1, ans2;
for(i=1; i<=N+1; i++) {
ans1 = querySeg(0, 0, traList[i].x[0][0]-1, 1, Nseg[0][0], Nseg[0][1]);
ans2 = querySeg(1, 0, traList[i].x[1][0]-1, 1, Nseg[1][0], Nseg[1][1]);
if(debug) cout << endl;
if(debug) cout << i << " " << ans1.val_m+1 << " " << ans1.val_mc << endl;
if(debug) cout << i << " " << ans2.val_m+1 << " " << ans2.val_mc << endl;
if(ans1.val_m > ans2.val_m) {
ans1.val_m = ans2.val_m; ans1.val_mc = ans2.val_mc;
}
updateSeg(0, traList[i].x[0][1], ans1.val_m + 1, ans1.val_mc, 1, Nseg[0][0], Nseg[0][1]);
updateSeg(1, traList[i].x[1][1], ans1.val_m + 1, ans1.val_mc, 1, Nseg[1][0], Nseg[1][1]);
if(debug) cout << i << " " << ans1.val_m+1 << " " << ans1.val_mc << endl;
}
cout << ans1.val_m << " " << ans1.val_mc << endl;
}
Compilation message (stderr)
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |