# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1035802 | Requiem | Sailing Race (CEOI12_race) | C++17 | 3068 ms | 19080 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.
#include<bits/stdc++.h>
//#define int long long
#define pb push_back
#define fast ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
#define MOD 1000000007
#define inf 1e18
#define fi first
#define se second
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define sz(a) ((int)(a).size())
#define endl '\n'
#define pi 3.14159265359
#define TASKNAME "sailrace"
template<typename T> bool maximize(T &res, const T &val) { if (res < val){ res = val; return true; }; return false; }
template<typename T> bool minimize(T &res, const T &val) { if (res > val){ res = val; return true; }; return false; }
using namespace std;
typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef vector<int> vi;
const int MAXN = 3e5 + 9;
string str;
int n, k;
vector<int> g[MAXN], backEdge[MAXN];
void extract(int curId){
int num = 0;
// cout << str << endl;
str = str + ' ';
for(int i = 0; i < str.length(); i++){
if (str[i] != ' ') {
num = num * 10 + (str[i] - '0');
// cout << num << ' ' << str[i] - '0' << endl;
}
else {
if (num != 0) {
g[curId].pb(num);
backEdge[num].pb(curId);
// cout << curId << ' ' << num << endl;
}
else break;
num = 0;
}
}
}
namespace subtask1{
bool check(){
return k == 0;
}
int dp[2][501][501], memo[2][501][501], backward = 0;
int bestI = 0, res = 0;
int goBack(int id){
return (id - backward <= 0) ? id - backward + n : (id - backward);
}
int goUp(int id){
return (id + backward) - ((id + backward > n) ? (n) : 0);
}
int memorization(int state, int Larc, int Rarc){
if (dp[state][Larc][Rarc] != -1) return dp[state][Larc][Rarc];
if (memo[state][goUp(Larc)][goUp(Rarc)] != -1) return memo[state][goUp(Larc)][goUp(Rarc)];
if (Larc >= Rarc) return 0;
dp[state][Larc][Rarc] = 0;
int cur = goUp((state) ? Rarc : Larc);
if (state == 0){
for(auto v: g[cur]){
int curV = goBack(v);
// cout << cur << ' ' << curV << ' ' << v << endl;
// cout << cur << ' ' << v << endl;
if (curV > Larc and curV <= Rarc) {
maximize(dp[0][Larc][Rarc], 1 + max(memorization(0, curV, Rarc), memorization(1, Larc + 1, curV)));
}
}
}
else{
for(auto v: g[cur]){
int curV = goBack(v);
if (curV >= Larc and curV < Rarc) {
maximize(dp[1][Larc][Rarc], 1 + max(memorization(0, curV, Rarc - 1), memorization(1, Larc, curV)));
}
}
}
memo[state][goUp(Larc)][goUp(Rarc)] = dp[state][Larc][Rarc];
// cout << "MEMO: " << state << ' ' << goUp(Larc) << ' ' << goUp(Rarc) << ' ' << memo[state][goUp(Larc)][goUp(Rarc)] << endl;
// cout << "DP: " << state << ' ' << Larc << ' ' << Rarc << ' ' << dp[state][Larc][Rarc] << endl;
return dp[state][Larc][Rarc];
}
int modify(int x){
return (x > n) ? (x - n) : x;
}
bool onRange(int l, int r, int x){
return x >= l and x <= r;
}
bool onArc(int l, int r, int x){
l = modify(l);
r = modify(r);
if (l > r) r += n;
return onRange(l, r, x) | onRange(l, r, x + n);
}
int dist(int i, int j){
i = modify(i);
j = modify(j);
return min(abs(i - j), abs(i + n - j));
}
bool RightArc(int l, int r, int x){
if (l > r) {
r += n;
}
return dist(r, x) < dist(l, x);
}
void solve(int print = 1){
memset(memo, -1, sizeof(memo));
for(int i = 1;i <= n; i++){
memset(dp, -1, sizeof(dp));
backward = i - 1;
// cout << i << endl;
int mx = memorization(0, 1, n);
if (maximize(res, mx)){
bestI = i;
}
// cout << endl;
}
if (print == 1) cout << res << endl;
if (print == 1) cout << bestI << endl;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
for(int state = 0; state < 2; state++){
if (memo[state][i][j] == -1) memo[state][i][j] = 0;
}
}
}
for(int i = 1; i <= n; i++){
for(auto v: g[i]){
maximize(memo[0][i][v], 1);
maximize(memo[1][v][i], 1);
}
}
for(int len = 1; len <= n; len++){
for(int i = 1, j = i + len - 1; i <= n; i++){
if (j > n) j -= n;
for(int state = 0; state < 2; state++){
int cur = (state == 0) ? i : j;
for(auto v: backEdge[cur]){
if (!onArc(i, j, v)) {
if (RightArc(i, j, v)) maximize(memo[1][i][v], memo[state][i][j] + 1);
else maximize(memo[0][v][j], memo[state][i][j] + 1);
// if (i == 3 and j == 5) cout << cur << ' ' << v << ' ' << memo[0][2][5] << endl;
}
}
}
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
for(int state = 0; state < 2; state++){
// cout << state << ' ' << i << ' ' << j << ' ' << memo[state][i][j] << endl;
}
}
}
}
}
namespace subtask2{
bool check(){
return k == 1;
}
int backward = 0;
int goVirtual(int id){
return (id - backward <= 0) ? id - backward + n : (id - backward);
}
int goOrigin(int id){
return (id + backward) - ((id + backward > n) ? (n) : 0);
}
int dpRight[505], dpLeft[505];
int solveRight(int cur, int intersect){
if (dpRight[cur] != -1) return dpRight[cur];
int u = goOrigin(cur);
dpRight[cur] = 0;
for(auto v: g[u]){
int curV = goVirtual(v);
if (curV < cur and curV > 1){
maximize(dpRight[cur], solveRight(curV, intersect) + 1);
}
else if (curV > intersect and cur != intersect) {
maximize(dpRight[cur], subtask1::memo[1][goOrigin(intersect + 1)][goOrigin(curV)] + 1);
maximize(dpRight[cur], subtask1::memo[0][goOrigin(curV)][goOrigin(n)] + 1);
}
}
// cout << "CUR: " << u << ' ' << cur << ' ' << dpRight[cur] << endl;
return dpRight[cur];
}
int solveLeft(int cur, int intersect){
if (dpLeft[cur] != -1) return dpLeft[cur];
int u = goOrigin(cur);
dpLeft[cur] = 0;
for(auto v: g[u]){
int curV = goVirtual(v);
if (curV > cur){
maximize(dpLeft[cur], solveLeft(curV, intersect) + 1);
}
else if (curV > 1 and curV < intersect and cur != intersect) {
maximize(dpLeft[cur], subtask1::memo[0][goOrigin(curV)][goOrigin(intersect - 1)] + 1);
maximize(dpLeft[cur], subtask1::memo[1][goOrigin(2)][goOrigin(curV)] + 1);
}
}
// cout << "LEFTCUR: " << intersect << ' ' << u << ' ' << cur << ' ' << dpLeft[cur] << endl;
return dpLeft[cur];
}
void solve(){
subtask1::solve(0);
int res = subtask1::res, bestI = subtask1::bestI;
for(int i = 1; i <= n; i++){
backward = i - 1;
for(auto v: g[i]){
memset(dpRight, -1, sizeof(dpRight));
memset(dpLeft, -1, sizeof(dpLeft));
// cout << 1 << ' ' << goVirtual(v) << endl;
int m1 = 0, m2 = 0;
m1 = solveRight(goVirtual(v), goVirtual(v)) + 1;
m2 = solveLeft(goVirtual(v), goVirtual(v)) + 1;
if (maximize(res, m1) or maximize(res, m2)){
bestI = i;
}
}
}
cout << res << endl;
cout << bestI << endl;
}
}
main()
{
fast;
if (fopen(TASKNAME".inp","r")){
freopen(TASKNAME".inp","r",stdin);
freopen(TASKNAME".out","w",stdout);
}
cin >> n >> k;
cin.ignore();
for(int i = 1; i <= n; i++){
getline(cin, str);
extract(i);
}
if (subtask1::check()) return subtask1::solve(), 0;
if (subtask2::check()) return subtask2::solve(), 0;
}
/**
Warning:
- MLE / TLE?
- Gioi han mang?
- Gia tri max phai luon gan cho -INF
- long long co can thiet khong?
- tran mang.
- code can than hon
- Nho sinh test de tranh RTE / TLE
--> Coi lai truoc khi nop
**/
Compilation message (stderr)
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |