Submission #213252

#TimeUsernameProblemLanguageResultExecution timeMemory
213252zscoderTwo Dishes (JOI19_dishes)C++17
100 / 100
8130 ms369528 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #pragma GCC optimize("unroll-loops,no-stack-protector") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") using namespace std; using namespace __gnu_pbds; #define fi first #define se second #define mp make_pair #define pb push_back typedef long long ll; typedef pair<ll,ll> ii; typedef vector<ll> vi; typedef unsigned long long ull; typedef long double ld; typedef tree<ii, null_type, less<ii>, rb_tree_tag, tree_order_statistics_node_update> pbds; vector<ll> a,b,s,p,q,t; vector<ii> F[1001111]; const ll INF = ll(3e18); vector<pair<ii,ll> > G[1001111]; struct node { ll v; ll upd,add; }; node st[4000011]; void build(int id, int l, int r) { st[id].v=st[id].add=0; //i shouldn't have -ves anyway, or should I? st[id].upd=-INF; if(r-l<2) return ; int mid=(l+r)>>1; build(id*2,l,mid); build(id*2+1,mid,r); } void combine(int id) { st[id].v=max(st[id*2].v,st[id*2+1].v); } void push(int id, int l, int r) { if(st[id].upd!=-INF) { st[id].v=st[id].upd; if(r-l>=2) { st[id*2].upd=st[id].upd; st[id*2].add=0; st[id*2+1].upd=st[id].upd; st[id*2+1].add=0; } } if(st[id].add!=0) { st[id].v+=st[id].add; if(r-l>=2) { st[id*2].add+=st[id].add; st[id*2+1].add+=st[id].add; } } st[id].upd=-INF; st[id].add=0; } void update(int id, int l, int r, int ql, int qr, ll v) { push(id,l,r); if(ql>=r||l>=qr) return ; if(l>=ql&&r<=qr) { //cerr<<l<<' '<<r<<' '<<ql<<' '<<qr<<' '<<v<<'\n'; st[id].upd=v; st[id].add=0; push(id,l,r); return ; } int mid=(l+r)>>1; update(id*2,l,mid,ql,qr,v); update(id*2+1,mid,r,ql,qr,v); combine(id); } void add(int id, int l, int r, int ql, int qr, ll v) { push(id,l,r); if(ql>=r||l>=qr) return ; if(l>=ql&&r<=qr) { //assert(st[id].upd==-INF); st[id].add+=v; push(id,l,r); return ; } int mid=(l+r)>>1; add(id*2,l,mid,ql,qr,v); add(id*2+1,mid,r,ql,qr,v); combine(id); } int find_left(int id, int l, int r, ll x) //or none? { push(id,l,r); if(st[id].v<x) return -1; if(r-l<2) return l; int mid=(l+r)>>1; ll val = st[id*2].v; if(st[id*2].upd!=-INF) val=st[id*2].upd; val+=st[id*2].add; if(val>=x) { return find_left(id*2,l,mid,x); } else { return find_left(id*2+1,mid,r,x); } } ll query(int id, int l, int r, int ql, int qr) { push(id,l,r); if(ql>=r||l>=qr) return -INF; if(l>=ql&&r<=qr) return st[id].v; int mid=(l+r)>>1; return max(query(id*2,l,mid,ql,qr),query(id*2+1,mid,r,ql,qr)); } ll dp[2111][2111]; int main() { //freopen("03-03.txt","r",stdin); int n,m; scanf("%d %d",&n,&m); a.resize(n); s.resize(n); p.resize(n); b.resize(m); t.resize(m); q.resize(m); for(int i=0;i<n;i++) { scanf("%lld %lld %lld",&a[i],&s[i],&p[i]); if(i>0) a[i]+=a[i-1]; } for(int i=0;i<m;i++) { scanf("%lld %lld %lld",&b[i],&t[i],&q[i]); if(i>0) b[i]+=b[i-1]; } ll ans = 0; for(int i=0;i<m;i++) { if(b[i]>t[i]) continue; if(b[i]+a[n-1]<=t[i]) {ans+=q[i]; continue;} //min j such that b_i+a_j>t[i] int ptr = upper_bound(a.begin(),a.end(),t[i]-b[i])-a.begin(); ans+=q[i]; //cerr<<i<<' '<<ptr+1<<'\n'; F[i].pb({ptr+1,-q[i]}); } for(int i=0;i<n;i++) { if(a[i]>s[i]) continue; if(a[i]+b[m-1]<=s[i]){ans+=p[i]; continue;} int ptr = upper_bound(b.begin(),b.end(),s[i]-a[i])-b.begin(); ptr--; //cerr<<ptr+1<<' '<<i+1<<' '<<p[i]<<'\n'; F[ptr+1].pb({i+1,p[i]}); } for(int i=0;i<m;i++) { sort(F[i].begin(),F[i].end()); ll sum=0; int l=0; for(int j=0;j<F[i].size();j++) { //cerr<<i<<' '<<F[i][j].fi<<' '<<F[i][j].se<<'\n'; if(j+1<F[i].size()&&F[i][j+1].fi==F[i][j].fi) { F[i][j+1].se+=F[i][j].se; continue; } if(l<=F[i][j].fi-1) { G[i].pb({{l,F[i][j].fi-1},sum}); } l=F[i][j].fi; sum+=F[i][j].se; } if(l<=n) G[i].pb({{l,n},sum}); } build(1,0,n+1); for(int i=0;i<m;i++) { vector<pair<ii,ii> > updates; ll lasnum = -INF*2; for(int j=0;j<G[i].size();j++) { int l = G[i][j].fi.fi; int r = G[i][j].fi.se; ll v = G[i][j].se; //cerr<<"UPDATE : "<<i<<' '<<l<<' '<<r<<' '<<v<<'\n'; cerr<<"LASNUM = "<<lasnum<<'\n'; int gleft = find_left(1,0,n+1,lasnum-v+1); //cerr<<"GLEFT : "<<gleft<<'\n'; if(gleft==-1) gleft=n+100; if(l<=gleft-1) updates.pb({{l,min(r,gleft-1)},{1,lasnum}}); if(gleft<=r) updates.pb({{max(gleft,l),r},{0,v}}); if(gleft<=r) lasnum=max(lasnum,v+query(1,0,n+1,r,r+1)); } for(auto X:updates) { if(X.se.fi) update(1,0,n+1,X.fi.fi,X.fi.se+1,X.se.se); //update else add(1,0,n+1,X.fi.fi,X.fi.se+1,X.se.se); } /* for(int j=0;j<G[i].size();j++) { int l = G[i][j].fi.fi; int r = G[i][j].fi.se; ll v = G[i][j].se; for(int k=l;k<=r;k++) { dp[i+1][k]=dp[i][k]+v; } } for(int k=1;k<=n;k++) dp[i+1][k]=max(dp[i+1][k],dp[i+1][k-1]); bool problem=0; for(int j=0;j<=n;j++) { if(dp[i+1][j]!=query(1,0,n+1,j,j+1)){problem=1; break;} } if(problem) { cerr<<"ROW "<<i+1<<'\n'; for(int j=0;j<=n;j++) { cerr<<dp[i+1][j]<<' '; } cerr<<'\n'; for(int j=0;j<=n;j++) { cerr<<query(1,0,n+1,j,j+1)<<' '; } cerr<<'\n'; cerr<<'\n'; } */ /* for(int j=0;j<=n;j++) { query(1,0,n+1,j,j+1); } */ } //cout<<ans+dp[m][n]<<'\n'; cout<<query(1,0,n+1,0,n+1)+ans<<'\n'; }

Compilation message (stderr)

dishes.cpp: In function 'int main()':
dishes.cpp:172:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int j=0;j<F[i].size();j++)
               ~^~~~~~~~~~~~
dishes.cpp:175:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    if(j+1<F[i].size()&&F[i][j+1].fi==F[i][j].fi)
       ~~~^~~~~~~~~~~~
dishes.cpp:194:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int j=0;j<G[i].size();j++)
               ~^~~~~~~~~~~~
dishes.cpp:135:16: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  int n,m; scanf("%d %d",&n,&m);
           ~~~~~^~~~~~~~~~~~~~~
dishes.cpp:140:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%lld %lld %lld",&a[i],&s[i],&p[i]);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dishes.cpp:145:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%lld %lld %lld",&b[i],&t[i],&q[i]);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...