Submission #328533

#TimeUsernameProblemLanguageResultExecution timeMemory
328533MonkeyKingSalesman (IOI09_salesman)C++14
100 / 100
2760 ms60780 KiB
//Original Code: //#include <self/utility> //#include <self/debug> //using namespace std; // // ////quality guarantee //template <typename T> //struct SegmentTreeMaxUpdate //[) //{ // T minValue = -1e9; // T *data = 0; // T *tag = 0; // int nn; // int size() // { // return nn; // } // void init(int size) // { // if (data) // delete data; // if (tag) // delete tag; // nn = 1; // while (nn < size) // { // nn <<= 1; // } // data = new T[nn * 2 + 5]; // tag = new T[nn * 2 + 5]; // for (int i = 0; i <= nn * 2; i++) // { // data[i] = minValue; // tag[i] = minValue; // } // } // void pushdown(int x) // { // if (x >= nn || tag[x]<=minValue) return; // data[x * 2] = max(data[x * 2], tag[x]); // data[x * 2 + 1] = max(data[x * 2 + 1], tag[x]); // tag[x * 2] = max(tag[x * 2], tag[x]); // tag[x * 2 + 1] = max(tag[x * 2 + 1], tag[x]); // tag[x] = minValue; // } // void update(int pos, T value) // { // update(pos, pos + 1, value); // } // void update(int ql, int qr, T value) // { // update(1, 0, nn, ql, qr, value); // } // void update(int x, int l, int r, int ql, int qr, T value) // { // if (l >= qr || r <= ql) // return; // pushdown(x); // if (l >= ql && r <= qr) // { // data[x] = max(data[x], value); // tag[x] = max(tag[x], value); // return; // } // update(x * 2, l, l + r >> 1, ql, qr, value); // update(x * 2 + 1, l + r >> 1, r, ql, qr, value); // data[x] = max(data[x * 2], data[x * 2 + 1]); // } // T query(int pos) // { // return query(pos,pos+1); // } // T query(int ql, int qr) // { // return query(1, 0, nn, ql, qr); // } // T query(int x, int l, int r, int ql, int qr) // { // if (l >= qr || r <= ql) // return minValue; // pushdown(x); // if (l >= ql && r <= qr) // { // return data[x]; // } // return max(query(x * 2, l, l + r >> 1, ql, qr), query(x * 2 + 1, l + r >> 1, r, ql, qr)); // } // ~SegmentTreeMaxUpdate() // { // delete data; // delete tag; // } //}; // //struct SegmentTreeFast:public SegmentTreeMaxUpdate <int> //{ // inline void update(int pos,int value) // { // pos+=nn; // while(pos) // { // chmax(data[pos],value); // pos>>=1; // } // } //}; // //SegmentTreeFast sgt1; //SegmentTreeFast sgt2; //SegmentTreeMaxUpdate <int> sgt3; //SegmentTreeMaxUpdate <int> sgt4; //int n,u,d,s; //vector <pii> fairs[500005]; // //namespace DEBUG //{ // vector <int> positions={1,2,3,4,5}; // inline void printProfit() // { // for(auto &pos:positions) // { // // assert(sgt1.query(pos)+pos*d==sgt2.query(pos)-pos*u); // cout<<sgt1.query(pos)-pos*d<<' '; // } // cout<<endl; // } //} //using namespace DEBUG; // //int main() //{ // freopen("input.txt","r",stdin); // scanf("%d%d%d%d",&n,&u,&d,&s); // for(int i=0;i<n;i++) // { // int x,y,z; // scanf("%d%d%d",&x,&y,&z); // fairs[x].push_back(mp(y,z)); // } // sgt1.init(500005); // sgt2.init(500005); // sgt3.init(500005); // sgt4.init(500005); // sgt1.update(s,s*d); // sgt2.update(s,-s*u); // fairs[500003].push_back(mp(s,0)); // for(int i=0;i<500005;i++) // { // // ????? // if(fairs[i].empty()) continue; // if(fairs[i].size()==1) // { // int pos=fairs[i][0].first; // int p=fairs[i][0].second; // int realCost=p+max(sgt1.query(0,pos+1)-pos*d,sgt2.query(pos,500005)+pos*u); // sgt1.update(pos,realCost+pos*d); // sgt2.update(pos,realCost-pos*u); // continue; // } // sort(all(fairs[i])); // sgt3.update(0,500005,-inf); // for(auto &fair:fairs[i]) // { // int pos=fair.first; // sgt3.update(pos,max(sgt2.query(pos,500005)+pos*u+pos*d,max(sgt3.query(0,pos+1),sgt1.query(0,pos+1)))+fair.second); // } // reverse(all(fairs[i])); // sgt4.update(0,500005,-inf); // for(auto &fair:fairs[i]) // { // int pos=fair.first; // sgt4.update(pos,max(sgt1.query(0,pos+1)-pos*u-pos*d,max(sgt4.query(pos,500005),sgt2.query(pos,500005)))+fair.second); // } // for(auto &fair:fairs[i]) // { // int pos=fair.first; // int realCost=max(sgt3.query(pos)-pos*d,sgt4.query(pos)+pos*u); // sgt1.update(pos,realCost+pos*d); // sgt2.update(pos,realCost-pos*u); // } // } // int realCost=max(sgt1.query(s)-s*d,sgt2.query(s)+s*u); // cout<<realCost<<endl; // return 0; //} //substituted with C++ Inliner #ifndef _SELF_UTILITY #define _SELF_UTILITY 1 #include <numeric> #include <iostream> #include <algorithm> #include <cmath> #include <stdio.h> #include <stdlib.h> #include <vector> #include <map> #include <queue> #include <set> #include <string> #include <string.h> #include <stack> #include <assert.h> #include <bitset> #include <time.h> #define Endl endl #define mp make_pair #define ll long long #define ull unsigned long long #define pii pair<int,int> #define over(A) {cout<<A<<endl;exit(0);} #define all(A) A.begin(),A.end() #define quickcin ios_base::sync_with_stdio(false); #ifdef __TAKE_MOD int mod; #else #ifdef __TAKE_CONST_MOD const int mod=__TAKE_CONST_MOD; #else const int mod=1000000007; #endif #endif const int gmod=5; const int inf=1039074182; const double eps=1e-9; const ll llinf=2LL*inf*inf; template <typename T1,typename T2> inline void chmin(T1 &x,T2 b) {if(b<x) x=b;} template <typename T1,typename T2> inline void chmax(T1 &x,T2 b) {if(b>x) x=b;} inline void chadd(int &x,int b) {x+=b-mod;x+=(x>>31 & mod);} template <typename T1,typename T2> inline void chadd(T1 &x,T2 b) {x+=b;if(x>=mod) x-=mod;} template <typename T1,typename T2> inline void chmul(T1 &x,T2 b) {x=1LL*x*b%mod;} template <typename T1,typename T2> inline void chmod(T1 &x,T2 b) {x%=b,x+=b;if(x>=b) x-=b;} template <typename T> inline T mabs(T x) {return (x<0?-x:x);} #endif using namespace std; #ifndef _SELF_DEBUG #define _SELF_DEBUG 1 #ifndef _SELF_OPERATOR #define _SELF_OPERATOR 1 using namespace std; template <typename T> ostream &operator<<(ostream &cout, vector<T> vec) { cout << "{"; for (int i = 0; i < (int)vec.size(); i++) { cout << vec[i]; if (i != (int)vec.size() - 1) cout << ','; } cout << "}"; return cout; } template <typename T> void operator*=(vector<T> &vec, int k) { for (auto &x : vec) x *= k; } template <typename T> void operator-=(vector<T> &a, const vector<T> &b) { assert(a.size() == b.size()); for (size_t it = 0; it < a.size(); it++) { a[it] -= b[it]; } } template <typename T> vector<T> operator*(const vector<T> &vec, int k) { vector<T> res(vec); res *= k; return res; } template <typename T1, typename T2> ostream &operator<<(ostream &cout, pair<T1, T2> p) { cout << "(" << p.first << ',' << p.second << ")"; return cout; } template <typename T, typename T2> ostream &operator<<(ostream &cout, set<T, T2> s) { vector<T> t; for (auto x : s) t.push_back(x); cout << t; return cout; } template <typename T, typename T2> ostream &operator<<(ostream &cout, multiset<T, T2> s) { vector<T> t; for (auto x : s) t.push_back(x); cout << t; return cout; } template <typename T> ostream &operator<<(ostream &cout, queue<T> q) { vector<T> t; while (q.size()) { t.push_back(q.front()); q.pop(); } cout << t; return cout; } template <typename T1, typename T2, typename T3> ostream &operator<<(ostream &cout, map<T1, T2, T3> m) { for (auto &x : m) { cout << "Key: " << x.first << ' ' << "Value: " << x.second << endl; } return cout; } template <typename T> T operator*(vector<T> v1, vector<T> v2) { assert(v1.size() == v2.size()); int n = v1.size(); T res = 0; for (int i = 0; i < n; i++) { res += v1[i] * v2[i]; } return res; } template <typename T1, typename T2> pair<T1, T2> operator+(pair<T1, T2> x, pair<T1, T2> y) { return make_pair(x.first + y.first, x.second + y.second); } template <typename T1, typename T2> void operator+=(pair<T1, T2> &x, pair<T1, T2> y) { x.first += y.first; x.second += y.second; } template <typename T1, typename T2> pair<T1, T2> operator-(pair<T1, T2> x) { return make_pair(-x.first, -x.second); } template <typename T> vector<vector<T>> operator~(vector<vector<T>> vec) { vector<vector<T>> v; int n = vec.size(), m = vec[0].size(); v.resize(m); for (int i = 0; i < m; i++) { v[i].resize(n); } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { v[i][j] = vec[j][i]; } } return v; } #endif void print0x(int x) { std::vector <int> vec; while(x) { vec.push_back(x&1); x>>=1; } std::reverse(vec.begin(),vec.end()); for(int i=0;i<(int)vec.size();i++) { std::cout<<vec[i]; } std::cout<<' '; } template <typename T> void print0x(T x,int len) { std::vector <int> vec; while(x) { vec.push_back(x&1); x>>=1; } reverse(vec.begin(),vec.end()); for(int i=(int)vec.size();i<len;i++) { putchar('0'); } for(size_t i=0;i<vec.size();i++) { std::cout<<vec[i]; } std::cout<<' '; } #endif using namespace std; //quality guarantee template <typename T> struct SegmentTreeMaxUpdate //[) { T minValue = -1e9; T *data = 0; T *tag = 0; int nn; int size() { return nn; } void init(int size) { if (data) delete data; if (tag) delete tag; nn = 1; while (nn < size) { nn <<= 1; } data = new T[nn * 2 + 5]; tag = new T[nn * 2 + 5]; for (int i = 0; i <= nn * 2; i++) { data[i] = minValue; tag[i] = minValue; } } void pushdown(int x) { if (x >= nn || tag[x]<=minValue) return; data[x * 2] = max(data[x * 2], tag[x]); data[x * 2 + 1] = max(data[x * 2 + 1], tag[x]); tag[x * 2] = max(tag[x * 2], tag[x]); tag[x * 2 + 1] = max(tag[x * 2 + 1], tag[x]); tag[x] = minValue; } void update(int pos, T value) { update(pos, pos + 1, value); } void update(int ql, int qr, T value) { update(1, 0, nn, ql, qr, value); } void update(int x, int l, int r, int ql, int qr, T value) { if (l >= qr || r <= ql) return; pushdown(x); if (l >= ql && r <= qr) { data[x] = max(data[x], value); tag[x] = max(tag[x], value); return; } update(x * 2, l, l + r >> 1, ql, qr, value); update(x * 2 + 1, l + r >> 1, r, ql, qr, value); data[x] = max(data[x * 2], data[x * 2 + 1]); } T query(int pos) { return query(pos,pos+1); } T query(int ql, int qr) { return query(1, 0, nn, ql, qr); } T query(int x, int l, int r, int ql, int qr) { if (l >= qr || r <= ql) return minValue; pushdown(x); if (l >= ql && r <= qr) { return data[x]; } return max(query(x * 2, l, l + r >> 1, ql, qr), query(x * 2 + 1, l + r >> 1, r, ql, qr)); } ~SegmentTreeMaxUpdate() { delete data; delete tag; } }; struct SegmentTreeFast:public SegmentTreeMaxUpdate <int> { inline void update(int pos,int value) { pos+=nn; while(pos) { chmax(data[pos],value); pos>>=1; } } }; SegmentTreeFast sgt1; SegmentTreeFast sgt2; SegmentTreeMaxUpdate <int> sgt3; SegmentTreeMaxUpdate <int> sgt4; int n,u,d,s; vector <pii> fairs[500005]; namespace DEBUG { vector <int> positions={1,2,3,4,5}; inline void printProfit() { for(auto &pos:positions) { // assert(sgt1.query(pos)+pos*d==sgt2.query(pos)-pos*u); cout<<sgt1.query(pos)-pos*d<<' '; } cout<<endl; } } using namespace DEBUG; int main() { // freopen("input.txt","r",stdin); scanf("%d%d%d%d",&n,&u,&d,&s); for(int i=0;i<n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); fairs[x].push_back(mp(y,z)); } sgt1.init(500005); sgt2.init(500005); sgt3.init(500005); sgt4.init(500005); sgt1.update(s,s*d); sgt2.update(s,-s*u); fairs[500003].push_back(mp(s,0)); for(int i=0;i<500005;i++) { // ????? if(fairs[i].empty()) continue; if(fairs[i].size()==1) { int pos=fairs[i][0].first; int p=fairs[i][0].second; int realCost=p+max(sgt1.query(0,pos+1)-pos*d,sgt2.query(pos,500005)+pos*u); sgt1.update(pos,realCost+pos*d); sgt2.update(pos,realCost-pos*u); continue; } sort(all(fairs[i])); sgt3.update(0,500005,-inf); for(auto &fair:fairs[i]) { int pos=fair.first; sgt3.update(pos,max(sgt2.query(pos,500005)+pos*u+pos*d,max(sgt3.query(0,pos+1),sgt1.query(0,pos+1)))+fair.second); } reverse(all(fairs[i])); sgt4.update(0,500005,-inf); for(auto &fair:fairs[i]) { int pos=fair.first; sgt4.update(pos,max(sgt1.query(0,pos+1)-pos*u-pos*d,max(sgt4.query(pos,500005),sgt2.query(pos,500005)))+fair.second); } for(auto &fair:fairs[i]) { int pos=fair.first; int realCost=max(sgt3.query(pos)-pos*d,sgt4.query(pos)+pos*u); sgt1.update(pos,realCost+pos*d); sgt2.update(pos,realCost-pos*u); } } int realCost=max(sgt1.query(s)-s*d,sgt2.query(s)+s*u); cout<<realCost<<endl; return 0; }

Compilation message (stderr)

salesman.cpp: In instantiation of 'T SegmentTreeMaxUpdate<T>::query(int, int, int, int, int) [with T = int]':
salesman.cpp:492:32:   required from 'T SegmentTreeMaxUpdate<T>::query(int, int) [with T = int]'
salesman.cpp:572:41:   required from here
salesman.cpp:503:32: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  503 |   return max(query(x * 2, l, l + r >> 1, ql, qr), query(x * 2 + 1, l + r >> 1, r, ql, qr));
      |                              ~~^~~
salesman.cpp:503:70: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  503 |   return max(query(x * 2, l, l + r >> 1, ql, qr), query(x * 2 + 1, l + r >> 1, r, ql, qr));
      |                                                                    ~~^~~
salesman.cpp: In instantiation of 'void SegmentTreeMaxUpdate<T>::update(int, int, int, int, int, T) [with T = int]':
salesman.cpp:469:3:   required from 'void SegmentTreeMaxUpdate<T>::update(int, int, T) [with T = int]'
salesman.cpp:578:28:   required from here
salesman.cpp:482:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  482 |   update(x * 2, l, l + r >> 1, ql, qr, value);
      |                    ~~^~~
salesman.cpp:483:23: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  483 |   update(x * 2 + 1, l + r >> 1, r, ql, qr, value);
      |                     ~~^~~
salesman.cpp: In function 'int main()':
salesman.cpp:550:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  550 |  scanf("%d%d%d%d",&n,&u,&d,&s);
      |  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
salesman.cpp:554:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  554 |   scanf("%d%d%d",&x,&y,&z);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...