タイトル説明
道路上に、位置は、整数Aで表されます
場合A = 0は、宮殿があります。場合<0 A> 0は、宮殿からメートルの東がある場合、Aは、西宮殿からメートルを有することです。
道路で、Nは、ラベルに1-Nと西から東に住居があります。各家には人を持っています。住居は、偶数点に存在します。
国の王は国民の物理的な下落が、もっと運動を取ることが必要であると考えているので、コマンドはすべての散歩に行く必要があります。すべての市民は、1秒は1メートルを行きます。それぞれの国民は、東または西に行きます。これらの方向は、あなたが知っています。誰もが歩き始めながら家を残すためにコマンドを発行した後。
しかし、国の国民は、二人は、彼らが停止してお話します満たせば道を歩いて、非常におしゃべりです。人々はまた話を停止(重複)を停止している人たちの上を歩くされています。一度停止し、私たちは散歩を忘れて、信じられないほどハードに話をします。
今すぐコマンドがT秒、国有Q重要な男を発行している、王は自分の位置を保持したかったです。あなたは彼がそれに答えることはできますか?
入力形式
最初の行は3、N、T、Qの整数です。
二つの整数愛は、Rの次のNライン。愛は、Riが1であれば、それは2であれば、その後、西へ、東行きます、座標の家です。愛は昇順で保証されたデータであり、2つの初期位置が一致があるでしょう。
次のQライン、各キング懸念で重要な数値を表す整数。
出力フォーマット
Qライン、一人一人の座標を表す整数。
20%データN <= 100、T <= 10000
さらに、データの20%N <= 5000
いくつかの西からのすべてのデータの20%を西から東、いくつかの連続した国家のすべての残りの部分に加え、
あい| | <= 10 ^ 18、| T | <= 10 ^ 18,1 <= Q <= N <= 100000データAiが、さらに100%です。
私はラインを分割しています------ ---------------------------------------- -------------------------------------------------- -------
副作用の問題:個々のシャフトのn個、第二所定の方向(東または西)であり、これらはt秒を求めて、移動しない人と出会う人後に、指定されたm個あたりの移動距離があります個々の位置が位置しています。
この質問は、最初の一目で確認することです、それはあなたが肯定的な解決策が出ているべきであると推定され、この問題の正の解は、ミスのよりでなければなりません。
(例えば西行き)歩いてすべての人、最後のピットストップを超えない3例の場合:
図1は、時間がアップして、あなたはどんな遠くに行くことはできません。
2、そして自分自身の人々は東に西に会っ歩きます。
図3は、それは彼自身の西は、彼が出会った人を扱った、会いました。
西への西のほとんどは、あなたは彼を制御することはできません。
同様に、私たちは東に行くために誰かを決定することができます。ライン上のカテゴリーの話。
Oの時間複雑度(N)。
コードを貼り付けると、理解しやすいです。
#include <ビット/ STDC ++ H> の#defineは長い長いっ
の#define融点make_pair用
の#define REPは(iは、、B)は、(i ++は; iが=(B)<I =(A)INT)のため
の#defineを(パーI、B)(iは(A = INT)のために、I> =(B); i--)使用して名前空間STDを、
typedefのペア < int型、int型 > PII。
typedefをダブルデシベル。
CONSTのINT N = 1E6 + 50 。
INTのN、Q、Q [N]。
長い長い ANS [N]、P [N] [ 2 ]、T。
インライン読み取り11(){
LL、X = 0、F = 1
;
チャー CH = GETCHAR()。
一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')、F = - 1。CH = GETCHAR();}
一方(CH> = ' 0 ' && CH <= ' 9 '){X =(x << 3)+(X << 1)+(CH ^ 48)。CH = GETCHAR();}
戻りのx *のF。
}
int型のmain(){
N)=(読み取り; T =読み取ります(); Q =読む();
担当者(I、1、n)はP [I] [ 0 ]読み取り=()、P [I] [ 1 ] = 読み取ります();
担当者(I、1、Q)Q [I] = (読み取り)
担当者(I、1 、n)の
場合(P [I] [ 1 ] == 2 ){
場合(I == 1 )
ANS [I] = P [I] [ 0 ] - T。
他の 場合(P [I- 1 ] [ 1 ] == 2 )
ANS [i]は = MAX(ANS [I- 1 ]、P [I] [0 ] - T)。
他 ANS [I] = MAX(P [I] [ 0 ] / 2 + P [I- 1 ] [ 0 ] / 2、P [I] [ 0 ] - T)。
}
(I、N、につき1 )
であれば(P [I] [ 1 ] == 1 ){
場合(I == N)は、
ANS [I] = P [I] [ 0 ] + T。
他の 場合(P [I + 1 ] [ 1 ] == 1 )
ANS [I]=分(ANS [I + 1 ]、P [I] [ 0 ] + T)。
他 ANS [I] =分(P [I] [ 0 ] / 2 + P [I + 1 ] [ 0 ] / 2、P [I] [ 0 ] + T)。
}
担当者は、(iは、1、Q)のprintf(" %Dの\ nは" 、[Q [I]をANS)。
リターン 0 ;
}
ただし、これはいない点が、この質問非正ソリューションの練習でもO(N logN個)は、一定の巨人小さな、正の解は、上記O(N)よりも高速に実行することです!
アイデア:各ミーティングポイントの前処理、及び位置又は+ -tは、それ以外のミーティングポイント、または出力する場合は、最も近いミーティングポイント、出力POS + tがPOS-Tに最も近い点が発生する可能性があるかどうかを確認します。バイナリ検索、もう少し詳しく説明し、特別な注意が必要です。
コード:
#include<bits/stdc++.h>
#define ll long long
#define mp make_pair
#define rep(i, a, b) for(int i = (a);i <= (b);i++)
#define per(i, a, b) for(int i = (a);i >= (b);i--)
using namespace std;
typedef pair<int, int> pii;
typedef double db;
const int N = 1e6 + 50;
const ll inf = 4557430888798830399;
ll n, t, q;
ll s[N], k = 0;
struct people{ll pos, dic, id; } a[N];
bool mycmp(people a, people b) {return a.pos < b.pos; }
inline ll read(){
ll x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
while(ch >='0' && ch <='9'){x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}
return x*f;
}
int main(){
n = read(); t = read(); q = read();
rep(i, 1, n) a[i].pos = read(), a[i].dic = read(), a[i].id = i;
sort(a+1, a+n+1, mycmp);
rep(i, 2, n){
if(a[i].dic == 2 && a[i-1].dic == 1) s[++k] = (a[i].pos+a[i-1].pos)>>1;
}
s[0] = -inf, s[k+1] = inf;
rep(i, 1, q){
ll x = read();
ll posx = a[a[x].id].pos, flag = a[a[x].id].dic;
ll l = 1, r = k, mid;
while(l < r){
mid = (l+r)>>1;
if(flag == 1){
if(s[mid] < posx) l = mid+1;
if(s[mid] > posx) r = mid;
}
if(flag == 2){
if(mid == l) mid++;
if(s[mid] < posx) l = mid;
if(s[mid] > posx) r = mid-1;
}
}
mid = l;
if(s[mid] < posx && flag == 2){
if(s[mid+1] < posx && s[mid+1] != inf) mid++;
}
if(s[mid] > posx && flag == 1){
if(s[mid-1] > posx && s[mid-1] != inf) mid--;
}
if(flag == 1){
if(s[mid] > posx+t && s[mid] > posx) printf("%lld\n", posx+t);
else if(s[mid] < posx) printf("%lld\n", posx+t);
else if(s[mid] < posx+t && s[mid] > posx) printf("%lld\n", s[mid]);
else printf("%lld\n", s[mid]);
}
if(flag == 2){
if(s[mid] < posx-t && s[mid] < posx) printf("%lld\n", posx-t);
else if(s[mid] > posx-t && s[mid] < posx) printf("%lld\n", s[mid]);
else if(s[mid] > posx) printf("%lld\n", posx-t);
else printf("%lld\n", s[mid]);
}
}
return 0;
}
好了,这道题就这么愉快地结束了。