Submission #48581

#TimeUsernameProblemLanguageResultExecution timeMemory
48581NamnamseoBulldozer (JOI17_bulldozer)C++17
100 / 100
1848 ms94664 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pp; typedef pair<ll,ll> pll; void read(int& x){ scanf("%d",&x); } void read(ll& x){ scanf("%lld",&x); } template<typename T,typename... Args> void read(T& a,Args&... b){ read(a); read(b...); } #define all(x) (x).begin(),(x).end() #define pb push_back #define eb emplace_back #define x first #define y second #define DBG if(0) int n; typedef tuple<int,int,int> Mine; Mine p[2010]; struct Kumi { ll x, y; Kumi(ll x_=0, ll y_=0){ x = x_; y = y_; if((x<0 && y==0) || y<0) x=-x, y=-y; } bool operator<(const Kumi& r) const { return x*r.y > y*r.x; } bool operator==(const Kumi& r) const { return x*r.y == y*r.x; } }; void in(){ read(n); //n = 2e3; //assert(RAND_MAX == 32767); for(int i=1; i<=n; ++i){ if(1){ int x, y, z; read(x, y, z); p[i] = make_tuple(x, y, z); } else { for(;;){ int x=rand(); int y=rand(); //int x = (rand() << 15) + rand(); //int y = (rand() << 15) + rand(); x = min(x, int(1e9)); y = min(y, int(1e9)); bool flg=1; for(int j=1; j<i; ++j) if(get<0>(p[j]) == x && get<1>(p[j]) == y){ flg=0; break; } if(flg){ p[i] = make_tuple(x, y, min(int(1e9), // (rand()<<15) + rand() rand() )); break; } } } } } Kumi operator-(const Mine& a, const Mine& b){ return {get<1>(b)-get<1>(a), get<0>(a)-get<0>(b)}; } pair<Kumi, int> kumis[2001*2000]; int Kn; void Build(){ for(int i=1; i<n; ++i){ for(int j=i+1; j<=n; ++j){ kumis[Kn++]= make_pair(p[i]-p[j], i); kumis[Kn++]= make_pair(p[i]-p[j], j); } } sort(kumis, kumis+Kn); Kn = unique(kumis, kumis+Kn) - kumis; } int ind[2010]; int rev[2010]; struct CuteSegtree { static const int M = 2048; ll sum[M<<1]; ll ls[M<<1]; ll rs[M<<1]; ll mg[M<<1]; int l[M<<1]; int r[M<<1]; void init(int L=1, int R=n, int p=1){ l[p]=L; r[p]=R; if(L == R) return; int mid=(L+R)/2; init(L, mid, p*2); init(mid+1, R, p*2+1); } void put(int pt, ll v){ int p=1; while(true){ if(l[p] == r[p]) break; int mid=(l[p]+r[p])/2; p*=2; if(mid<pt) ++p; } sum[p] = v; ls[p] = rs[p] = mg[p] = max(0LL, v); p/=2; while(p){ sum[p] = sum[p*2] + sum[p*2+1]; ls[p] = max(ls[p*2], sum[p*2] + ls[p*2+1]); rs[p] = max(rs[p*2+1], sum[p*2+1] + rs[p*2]); mg[p] = max(rs[p*2] + ls[p*2+1], max(mg[p*2], mg[p*2+1])); p/=2; } } /*void put(int pt, ll v, int l=1, int r=n, int p=1){ if(l == r){ sum[p] = v; ls[p] = rs[p] = mg[p] = max(0LL, v); return; } int mid=(l+r)/2; if(pt <= mid) put(pt, v, l, mid, p*2); else put(pt, v, mid+1, r, p*2+1); sum[p] = sum[p*2] + sum[p*2+1]; ls[p] = max(ls[p*2], sum[p*2] + ls[p*2+1]); rs[p] = max(rs[p*2+1], sum[p*2+1] + rs[p*2]); mg[p] = max(rs[p*2] + ls[p*2+1], max(mg[p*2], mg[p*2+1])); }*/ } seg; int main() { in(); for(int i=1; i<=n; ++i) ind[i] = i; sort(ind+1, ind+n+1, [&](const int& a, const int& b){ ll ax, ay; tie(ax, ay, ignore) = p[a]; ll bx, by; tie(bx, by, ignore) = p[b]; return ax < bx; }); DBG { printf("Initial: "); for(int i=1; i<=n; ++i) printf("%d ", ind[i]); putchar(10); } seg.init(); for(int i=1; i<=n; ++i){ seg.put(i, get<2>(p[ind[i]])); rev[ind[i]]=i; } ll ans = seg.mg[1]; Build(); if(1) for(int i=0; i<Kn;){ int j=i; vector<int> v; for(;j<Kn && kumis[i].x == kumis[j].x; ++j) v.pb(kumis[j].y); ll ccx = kumis[i].x.x, ccy=kumis[i].x.y; DBG { printf("Swap by %lld,%lld : ", ccx, ccy); for(int t:v) printf("%d ", t); putchar(10); } sort(all(v), [&](const int& a, const int& b){ ll va = ccx*get<0>(p[a]) + ccy*get<1>(p[a]); ll vb = ccx*get<0>(p[b]) + ccy*get<1>(p[b]); if(va != vb) return va<vb; va = -ccy*get<0>(p[a]) + ccx*get<1>(p[a]); vb = -ccy*get<0>(p[b]) + ccx*get<1>(p[b]); return va < vb; }); v.erase(unique(all(v)), v.end()); //0.9s vector<int> indices; for(int t:v) indices.pb(rev[t]); sort(all(indices)); // 0.2s int m = indices.size(); for(int i=0; i<m; ++i){ ind[indices[i]]=v[i]; rev[v[i]]=indices[i]; seg.put(indices[i], get<2>(p[v[i]])); } ans = max(ans, seg.mg[1]); DBG { printf("Resulting: "); for(int i=1; i<=n; ++i) printf("%d ", ind[i]); putchar(10); } i=j; } printf("%lld\n", ans); return 0; }

Compilation message (stderr)

bulldozer.cpp: In function 'void read(int&)':
bulldozer.cpp:6:25: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
 void read(int& x){ scanf("%d",&x); }
                    ~~~~~^~~~~~~~~
bulldozer.cpp: In function 'void read(ll&)':
bulldozer.cpp:7:24: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
 void read(ll& x){ scanf("%lld",&x); }
                   ~~~~~^~~~~~~~~~~
#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...