UOJ Test Round #1

  T1:数字比大小的本质是按(长度,字典序)比大小。

  T2首先发现单调性,二分答案,用堆模拟,$O(n\log^2 n)$。

    第二个log已经没有什么可优化的了,但是第一个可以做到线性。

    我们先将特殊题的p就当作是-1跑一边,设这个题的出现时间是tx,完成所需时间为sx,记录下每个题在[tx,T]上的出现时间。把所有题按优先级排序,可以发现如果找到了前i个满足出现时间之和为sx,那么这些时间区间正好可以被特殊题区间覆盖,找到这个i就确定了优先级,最后再模拟一遍即可。

    有个很容易忽视的问题,就是一定要保证得到的i是能让px尽量小的,这样才可以在总时间相同的情况下使特殊题最后做完,从而保证特殊题的完成时间就是T而不是T之前。

    当然按上述做法把优先级从低到高排序没有任何问题,但是如果从高到低排序最后相减就会出错了。

    为了这个问题调了一整个下午。

 1 #include<map>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<algorithm>
 5 #define rep(i,l,r) for (int i=l; i<=r; i++)
 6 typedef long long ll;
 7 using namespace std;
 8 
 9 const int N=300010;
10 const ll inf=1000000000000000000ll;
11 int n,pp,pos,s[N],sm[N];
12 ll mx,S,T,Ed[N];
13 struct P{ int t,s,p,id; }a[N];
14 priority_queue<P>Q;
15 map<ll,bool>mp;
16 
17 bool operator <(const P &a,const P &b){ return a.p<b.p; }
18 bool cmp(const P &a,const P &b){ return (a.t==b.t) ? a.p>b.p : a.t<b.t; }
19 bool cmp1(int x,int y){ return a[x].p<a[y].p; }
20 void F(int id,ll l,ll r){
21     l=max(l,S); r=min(r,T);
22     if (r>l) sm[id]+=r-l;
23 }
24 
25 int main(){
26     scanf("%d",&n); mp[0]=1;
27     rep(i,1,n){
28         scanf("%d%d%d",&a[i].t,&a[i].s,&a[i].p);
29         if (a[i].p==-1) S=a[i].t,pp=a[i].s;
30         mp[a[i].p]=1; a[i].id=i;
31     }
32     scanf("%lld",&T);
33     sort(a+1,a+n+1,cmp);
34     rep(i,1,n) s[i]=i;
35     sort(s+1,s+n+1,cmp1);
36     for (int i=1,j=1; i<=n; i=j){
37         for (; a[j].t==a[i].t; j++) Q.push(a[j]);
38         ll tim=a[i].t,ed=a[j].t;
39         if (ed==0) ed=inf;
40         while (!Q.empty()){
41             P x=Q.top(); Q.pop();
42             if (tim+x.s<=ed){
43                 F(x.id,tim,tim+x.s); tim+=x.s; mx=max(mx,tim);
44                 if (tim==ed) break;
45             }else { x.s-=ed-tim; F(x.id,tim,ed); mx=max(mx,ed); Q.push(x); break; }
46         }
47     }
48     ll res=0,ans=1;
49     while (mp.count(ans)) ans++;
50     rep(i,1,n){
51         res+=sm[a[s[i]].id];
52         if (res==pp){
53             //printf("%lld %lld %d %lld\n",S,res,pp,T);
54             //printf("%d %d %d\n",a[s[i]].p,a[s[i+1]].p,a[s[i+2]].p);
55             ans=(~a[s[i]].p) ? a[s[i]].p : a[s[i-1]].p;
56             while (mp.count(ans)) ans++;
57             break;
58         }
59     }
60     rep(i,1,n) if (a[i].p==-1) { a[i].p=ans; break; }
61     while (!Q.empty()) Q.pop();
62     for (int i=1,j=1; i<=n; i=j){
63         for (; a[j].t==a[i].t; j++) Q.push(a[j]);
64         ll tim=a[i].t,ed=a[j].t;
65         if (ed==0) ed=inf;
66         while (!Q.empty()){
67             P x=Q.top(); Q.pop();
68             if (tim+x.s<=ed) Ed[x.id]=tim+x.s,tim+=x.s;
69                 else { x.s-=ed-tim; Q.push(x); tim=ed; break; }
70         }
71     }
72     printf("%lld\n",ans);
73     rep(i,1,n) printf("%lld ",Ed[i]);
74     return 0;
75 }
UTR#2 T2

相关文章:

  • 2021-11-29
  • 2021-10-09
  • 2022-01-26
  • 2022-02-14
  • 2021-07-14
  • 2021-11-04
  • 2021-09-01
  • 2021-06-14
猜你喜欢
  • 2022-12-23
  • 2021-06-14
  • 2021-12-10
  • 2022-12-23
  • 2022-12-23
  • 2021-09-13
  • 2022-12-23
相关资源
相似解决方案