CodeChef - WIQ Waiting in a Queue
数据结构
题意
一个队列里面有1到n,n个任务。每个任务有个准备时间,有个持续时间。从1时刻开始检查队列中的任务,遇到一个任务,如果他没准备好,那么把它移到队尾。如果他准备好了,那么做它,完事后就移除。
思路
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#define M(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long LL;
const int MAXN=1000007;
const int oo=0x3f3f3f3f;
int sum[MAXN<<2];
void pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l, int r, int rt)
{
sum[rt]=0;
if(l==r) return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void update(int p, int c, int l, int r, int rt)
{
if(l==r) { sum[rt]+=c; return; }
int m=(l+r)>>1;
if(p<=m) update(p, c, lson);
else update(p, c, rson);
pushup(rt);
}
int query(int L, int R, int l, int r, int rt)
{
if(L>R) return 0;
if(L<=l&&r<=R) return sum[rt];
int m=(l+r)>>1;
int res=0;
if(L<=m) res+=query(L, R, lson);
if(m<R) res+=query(L, R, rson);
return res;
}
struct People
{
int i;
LL a, b;
LL res;
}peo[MAXN];
int ha[MAXN];
bool cmp1(People a, People b)
{
if(a.b==b.b) return a.i<b.i;
return a.b<b.b;
}
set<int> s;
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("ou1.txt", "w", stdout);
int T;scanf("%d", &T);
while(T--)
{
int n;scanf("%d", &n);
build(1, n, 1);
for(int i=1;i<=n;i++)
{
peo[i].i=i;
update(i, 1, 1, n, 1);
scanf("%lld", &peo[i].a);
}
for(int i=1;i<=n;i++)
{
scanf("%lld", &peo[i].b);
peo[i].b--;
}
sort(peo+1, peo+1+n, cmp1);
for(int i=1;i<=n;i++)
{
ha[peo[i].i]=i;
}
LL cur_tim=0;s.clear();
int ne=1;
int exi=n;
while(exi>0)
{
if(s.empty()&&ne<=n&&cur_tim+exi<=peo[ne].b) cur_tim+=(peo[ne].b-cur_tim)/exi*exi;
while(ne<=n&&peo[ne].b<cur_tim+exi) s.insert(peo[ne++].i);
set<int>::iterator it=s.begin();
int la=0, now=0;
while(it!=s.end())
{
now=(*it);
cur_tim+=query(la+1, now, 1, n, 1);
while(ne<=n&&peo[ne].b<cur_tim+exi) s.insert(peo[ne++].i);
if(cur_tim>peo[ha[now]].b)
{
update(now, -1, 1, n, 1);
cur_tim+=peo[ha[now]].a;
peo[ha[now]].res=cur_tim;
while(ne<=n&&peo[ne].b<cur_tim+exi) s.insert(peo[ne++].i);
exi--;
it++;
s.erase(now);
}
else
{
it++;
}
la=now;
}
cur_tim+=query(now+1, n, 1, n, 1);
}
for(int i=1;i<=n;i++)
{
printf("%lld%c", peo[ha[i]].res, i==n ? '\n' : ' ');
}
}
return 0;
}