这里会显示出您选择的修订版和当前版本之间的差别。
| 两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
|
2020-2021:teams:legal_string:jxm2001:contest:2020牛客国庆集训派对 [2020/10/07 21:13] jxm2001 |
2020-2021:teams:legal_string:jxm2001:contest:2020牛客国庆集训派对 [2020/10/07 21:26] (当前版本) jxm2001 [C、Expect to wait] |
||
|---|---|---|---|
| 行 254: | 行 254: | ||
| === 题意 === | === 题意 === | ||
| + | 给定 $n$ 个事件,时间分两种: | ||
| + | - $t$ 时刻有 $k$ 人借车 | ||
| + | - $t$ 时刻新加入 $k$ 辆车 | ||
| + | |||
| + | 接下来 $q$ 个询问,每次询问当初始时有 $b$ 辆车时所有人的等待时间和。 | ||
| === 题解 === | === 题解 === | ||
| + | |||
| + | 先假设初始时没有车,考虑根据初始事件构造“时间 $-$ 等待人数”图,则答案恰好为该图形围成的面积。 | ||
| + | |||
| + | 考虑初始时有 $b$ 辆车的情况,易知这等价于将图形向下移动 $b$ 个单位,同时删去小于 $0$ 的部分。 | ||
| + | |||
| + | 不难发现这同时等价于直线 $y=b$ 与原图形上方曲线围成面积。考虑将询问根据 $b$ 排序,利用扫描线法维护答案,时间复杂度 $O(n\log n)$。 | ||
| + | |||
| + | 需要注意无解情况的特判。另外发现也可以吉司机线段树区间置 $\max$ 再询问 $\text{sum}$ 无脑维护。 | ||
| + | |||
| + | <hidden 查看代码> | ||
| + | <code cpp> | ||
| + | const int MAXN=1e5+5; | ||
| + | struct Seg{ | ||
| + | int len,v; | ||
| + | bool operator < (const Seg &b)const{ | ||
| + | return v>b.v; | ||
| + | } | ||
| + | }seg[MAXN]; | ||
| + | struct Query{ | ||
| + | int v,idx; | ||
| + | bool operator < (const Query &b)const{ | ||
| + | return v>b.v; | ||
| + | } | ||
| + | }que[MAXN]; | ||
| + | LL ans[MAXN]; | ||
| + | int tim[MAXN],k[MAXN]; | ||
| + | int main() | ||
| + | { | ||
| + | int n=read_int(),q=read_int(); | ||
| + | _rep(i,1,n){ | ||
| + | char c=get_char(); | ||
| + | tim[i]=read_int(),k[i]=read_int(); | ||
| + | if(c=='+')k[i]=-k[i]; | ||
| + | } | ||
| + | int st=0; | ||
| + | _for(i,1,n){ | ||
| + | seg[i].len=tim[i+1]-tim[i]; | ||
| + | seg[i].v=st+=k[i]; | ||
| + | } | ||
| + | st+=k[n]; | ||
| + | st=max(0,st); | ||
| + | sort(seg+1,seg+n); | ||
| + | _for(i,0,q){ | ||
| + | que[i].v=read_int(); | ||
| + | que[i].idx=i; | ||
| + | } | ||
| + | sort(que,que+q); | ||
| + | int pos=1,slen=0; | ||
| + | LL sum=0; | ||
| + | _for(i,0,q){ | ||
| + | if(que[i].v<st){ | ||
| + | ans[que[i].idx]=-1; | ||
| + | continue; | ||
| + | } | ||
| + | if(i)sum+=1LL*(que[i-1].v-que[i].v)*slen; | ||
| + | while(pos<n&&que[i].v<seg[pos].v){ | ||
| + | slen+=seg[pos].len; | ||
| + | sum+=1LL*(seg[pos].v-que[i].v)*seg[pos].len; | ||
| + | pos++; | ||
| + | } | ||
| + | ans[que[i].idx]=sum; | ||
| + | } | ||
| + | _for(i,0,q){ | ||
| + | if(~ans[i]) | ||
| + | enter(ans[i]); | ||
| + | else | ||
| + | puts("INFINITY"); | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | </code> | ||
| + | </hidden> | ||