UOJ10 UTR #1 pyx的难题(堆)
显然优先级越高完成的越早,二分答案后用堆模拟就是O(nlog2n)的。考虑去一个log。先固定特殊题的优先级为最低,模拟一遍。这样在特殊题被扔过来到T的这段时间内,如果将特殊题的优先级提高至超过这其中某些时间段所做的题,这些时间就会空出来变为做特殊题。所以从小到大枚举优先级,直到空出来的时间恰好与做特殊题的时间相等即可。
有一种类似但错误的思路是,将特殊题优先级提高至超过从特殊题被扔过来到做完特殊题的这段时间内的某些时间段所做的题,让以此提前的时间为做完特殊题的时间-T。但实际上在让特殊题提前的过程中,可能会使原本某些在其之前做完的题的被扔过来的时间变到做完特殊题之后。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | #include<bits/stdc++.h> using namespace std; #define ll long long #define N 300010 char getc (){ char c= getchar (); while ((c< 'A' ||c> 'Z' )&&(c< 'a' ||c> 'z' )&&(c< '0' ||c> '9' )) c= getchar (); return c;} int gcd( int n, int m){ return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1; char c= getchar (); while (c< '0' ||c> '9' ) { if (c== '-' ) f=-1;c= getchar ();} while (c>= '0' &&c<= '9' ) x=(x<<1)+(x<<3)+(c^48),c= getchar (); return x*f; } int n,c[N],s[N]; ll ans[N],T; map< int , int > f; struct data { int t,s,p,i; bool operator <( const data&a) const { return p<a.p; } }a[N]; bool cmp( const data&a, const data&b) { return a.t<b.t; } priority_queue<data> q; signed main() { #ifndef ONLINE_JUDGE freopen ( "a.in" , "r" ,stdin); freopen ( "a.out" , "w" ,stdout); const char LL[]= "%I64d\n" ; #else const char LL[]= "%lld\n" ; #endif n=read(); for ( int i=1;i<=n;i++) a[i].t=read(),s[i]=a[i].s=read(),f[a[i].p=read()]=1,a[i].i=i; cin>>T; sort(a+1,a+n+1,cmp); bool flag=0; for ( int i=1;i<=n;i++) { int lst=a[i-1].t; while (!q.empty()&&lst<a[i].t) { data x=q.top();q.pop(); if (flag) c[x.i]+=min(min(T,1ll*a[i].t)-lst,1ll*x.s); if (a[i].t-lst>=x.s) lst+=x.s; else x.s-=a[i].t-lst,q.push(x),lst=a[i].t; if (lst>=T) {flag=0; break ;} } if (lst>=T) {flag=0; break ;} q.push(a[i]); if (a[i].p==-1) flag=1; } if (flag) { ll lst=a[n].t; while (!q.empty()) { data x=q.top();q.pop(); c[x.i]+=min(T-lst,1ll*x.s); lst+=x.s; if (lst>=T) break ; } } sort(a+1,a+n+1); ll t=0; for ( int i=1;i<=n;i++) { t+=c[a[i].i]; if (t==a[1].s) { if (i==1) a[1].p=1; else a[1].p=a[i].p; break ; } } while (f[a[1].p]) a[1].p++; cout<<a[1].p<<endl; sort(a+1,a+n+1,cmp); for ( int i=1;i<=n;i++) a[i].s=s[a[i].i]; while (!q.empty()) q.pop(); for ( int i=1;i<=n;i++) { int lst=a[i-1].t; while (!q.empty()&&lst<a[i].t) { data x=q.top();q.pop(); if (a[i].t-lst>=x.s) ans[x.i]=lst+=x.s; else x.s-=a[i].t-lst,q.push(x),lst=a[i].t; } q.push(a[i]); } ll lst=a[n].t; while (!q.empty()) { data x=q.top();q.pop(); ans[x.i]=lst+=x.s; } for ( int i=1;i<=n;i++) printf ( "%lld " ,ans[i]); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步