永不落幕的 zy
背景
人们的感情像洪水一样袭来,头晕目眩。
题目描述
zy 是一位拥有“共感”能力的少年,他总是能有意无意地感知别人的心情。
sm 是一位有着“心墙”的少女,她的感情无法传递出去。
就像命运一般,他们相遇了,仿佛 zy(的能力)就是为了 sm 而存在一样(事实上也确实如此) 。
sm 的心墙由许多迷茫组成,每个迷茫都希望从 X 轴上某一点去到另一点,而只有 zy 能消除 sm 的迷茫。
面对数量如此庞大的迷茫,zy 不曾想要放弃,但有些迷失了方向。
假设现在时间是
0
,zy 在心墙的
若现在 zy 携带的迷茫想要去的地点和心墙上剩下的迷茫中在他右边的个数大于等于左边,则 zy 会向右移动,反之向左。
若现在 sm 没有任何迷茫,则 zy 原地不动。
现在 zy 想知道,组成心墙的每个迷茫分别在什么时候消失。
为了尽快地让 zy 能拥抱 sm,请你帮帮他。
输入描述
第一行两个数
接下来
输出描述
样例输入
2 10
1 2 5
7 4 5
样例输出
5
9
样例解释
时刻
时刻
2
,zy 移动到了位置
时刻
5
,zy 移动到了位置 5,迷茫消失。
时刻
时刻
8
,zy 移动到了位置
时刻
9
,zy 移动到了位置
数据范围
对于
30%
的数据:
N
,
对于
60%
的数据:
N
,
对于
100%
的数据:
N
,
后记
我们的落幕,是新的开始。
附件
Solution
首先想到的方法是按时间模拟……
然后发现大样例中竟然有时间超过 int!!
于是便想会有实际操作(即有迷茫出现、加点或删点)的时间点,必然是跳着走的。
所以便想用平衡树来维护这个左右两边最近的可能发生事情的点。
结果打挂了,
0
<script type="math/tex" id="MathJax-Element-37">0</script> 分……。
神犇Wza表示他只用了一个STL:set,并没有打什么平衡树。
于是我也这么打了。
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#define LL long long
#define INF 922337203685775807LL
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
using namespace std;
struct Obj{
int a,b,t,num;
}obj[100010];
int n,m,now=1,z=1,Tot;
int want[100010],lft,rgt;
int here[100010],Time[100010];
LL end[100010];
bool go_before;
set<int>Splay;
set<int,greater<int> >Splay2;
vector<int>to[100010];
vector<int>frm[100010];
bool cmp(Obj x,Obj y){
return x.t<y.t;
}
LL nxtT(LL x){
return Time[lower_bound(Time+1,Time+n+1,x+1)-Time];
}
int main(){
#ifndef DEBUG
freopen("sm.in","r",stdin);
freopen("sm.out","w",stdout);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&obj[i].t,&obj[i].a,&obj[i].b);
obj[i].num=i;Time[i]=obj[i].t;
}
sort(obj+1,obj+n+1,cmp);
sort(Time+1,Time+n+1);
LL i=1;
while(1){
if(here[z]){
if(go_before)rgt-=here[z];
else lft-=here[z];
for(vector<int>::iterator it=to[z].begin();it!=to[z].end();it++){
want[obj[(*it)].b]++;
frm[obj[(*it)].b].push_back((*it));
if(obj[(*it)].b>z)rgt++;
else lft++;
Splay.insert(obj[(*it)].b);
Splay2.insert(obj[(*it)].b);
}
Splay.erase(z);
Splay2.erase(z);
to[z].clear();
here[z]=0;
}
if(want[z]){
if(go_before)rgt-=want[z];
else lft-=want[z];
Tot-=want[z];
for(vector<int>::iterator it=frm[z].begin();it!=frm[z].end();it++){
end[obj[(*it)].num]=i;
}
Splay.erase(z);
Splay2.erase(z);
frm[z].clear();
want[z]=0;
}
if(i==obj[now].t){
while(obj[now].t==i){
Tot++;
if(obj[now].a==z){
if(obj[now].b>z)rgt++;
else lft++;
want[obj[now].b]++;
frm[obj[now].b].push_back(now);
Splay.insert(obj[now].b);
Splay2.insert(obj[now].b);
now++;
continue;
}
Splay.insert(obj[now].a);
Splay2.insert(obj[now].a);
to[obj[now].a].push_back(now);
if(obj[now].a>z)rgt++;
else lft++;
here[obj[now].a]++;
now++;
}
}
if(!Tot){
i=nxtT(i);
if(now>n)break;
}
else if(rgt>=lft){
go_before=true;
LL tttt=i,nxtTT=nxtT(i);
if(rgt)i=Min(i+((*Splay.upper_bound(z))-z),(nxtTT==0?INF:nxtTT));
else i=nxtT(i);
z=i-tttt+z;
}
else{
go_before=false;
LL tttt=i,nxtTT=nxtT(i);
i=Min(i+(z-(*Splay2.upper_bound(z))),(nxtTT==0?INF:nxtTT));
z=z-(i-tttt);
}
}
for(int i=1;i<=n;i++)printf("%lld\n",end[i]);
return 0;
}