永不落幕的 zy
背景
人們的感情像洪水一樣襲來,頭暈目眩。
題目描述
zy 是一位擁有“共感”能力的少年,他總是能有意無意地感知別人的心情。
sm 是一位有着“心牆”的少女,她的感情無法傳遞出去。
就像命運一般,他們相遇了,彷彿 zy(的能力)就是爲了 sm 而存在一樣(事實上也確實如此) 。
sm 的心牆由許多迷茫組成,每個迷茫都希望從 X 軸上某一點去到另一點,而只有 zy 能消除 sm 的迷茫。
面對數量如此龐大的迷茫,zy 不曾想要放棄,但有些迷失了方向。
假設現在時間是
若現在 zy 攜帶的迷茫想要去的地點和心牆上剩下的迷茫中在他右邊的個數大於等於左邊,則 zy 會向右移動,反之向左。
若現在 sm 沒有任何迷茫,則 zy 原地不動。
現在 zy 想知道,組成心牆的每個迷茫分別在什麼時候消失。
爲了儘快地讓 zy 能擁抱 sm,請你幫幫他。
輸入描述
第一行兩個數
接下來
輸出描述
樣例輸入
2 10
1 2 5
7 4 5
樣例輸出
5
9
樣例解釋
時刻
時刻
時刻
時刻
時刻
時刻
數據範圍
對於
對於
對於
後記
我們的落幕,是新的開始。
附件
Solution
首先想到的方法是按時間模擬……
然後發現大樣例中竟然有時間超過 int!!
於是便想會有實際操作(即有迷茫出現、加點或刪點)的時間點,必然是跳着走的。
所以便想用平衡樹來維護這個左右兩邊最近的可能發生事情的點。
結果打掛了,
神犇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;
}