1. 程式人生 > >清北集訓Day1T3 LYK loves jumping

清北集訓Day1T3 LYK loves jumping

ons std win32 algorithm 樹狀數組 define badge sum love

題目描述

LYK在玩一個魔法遊戲,叫做跳躍魔法。 有n個點,每個點有兩個屬性hi和ti,表示初始高度,和下降高度。也就是說,它初始時高度為hi,一旦LYK踩在這個點上,由於重力的影響,這個點的高度會下降ti,當LYK離開這個點時,這個點的高度又會回到hi。 眾所周知的是,跳躍遊戲一般是往下跳的,每次LYK可以從一個點跳到任意一個高度不超過它的點,也就是說,當ti=0時,它可以跳到自己本來所在的點。 當沒地方可以跳的時候,LYK就會跳到地面,現在LYK想以第i個點為起點,問期望跳多少次能跳到地面。當然i可以是1~n中的任意一個數字。 若期望步數為無窮,輸出0.000。 設oo表示無窮大,X為一個數,有oo-X=oo,oo*X=oo,oo/X=oo,oo+X=oo。

輸入輸出格式

輸入格式:

第一行輸入一個數n,表示有n個點。 第二行輸入n個數,表示hi。 第三行輸入n個數,表示ti。

輸出格式:

輸出一行n個數,表示以當前點為起點時,期望跳幾次跳到地面(保留4位小數),若期望次數為無窮,輸出“0.0000”。

輸入輸出樣例

輸入樣例#1: 復制
4
4 2 2 3
0 1 0 0
輸出樣例#1: 復制
3.8333 1.0000 3.0000 3.5000

說明

對於20%的數據n<=5。 對於另外20%的數據所有hi都相等。 對於再另外20%的數據不存在ti=0。 對於再再另外20%的數據hi都互不相等。 對於100%的數據1<=n,hi<=10^5,0<=ti<=hi。

一道並不難的期望dp

推出樣例就相當於做完一半了

對於一個點,分$t=0$和$t!=0$兩種情況討論

技術分享圖片

然後拿個樹狀數組維護一下就好了

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1e6+10;
const double INF=1e16;
#define lb(x) (x&(-x))
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<
0||c>9){if(c==-)f=-1;c=getchar();} while(c>=0&&c<=9){x=x*10+c-0;c=getchar();} return x*f; } int N; struct node { int h,t,ID; double ans; bool operator < (const node &a) const { return a.h==h?t>a.t:h<a.h; } }a[MAXN],now; int comp(const node &a,const node &b) { return a.ID<b.ID; } namespace BIT { double T[MAXN]; void PointChange(int pos,double val) { while(pos<=N) { T[pos]+=val; pos+=lb(pos); } } double Sum(int pos) { double ans=0; while(pos) ans+=T[pos],pos-=lb(pos); return ans; } } int main() { #ifdef WIN32 freopen("a.in","r",stdin); #endif N=read(); for(int i=1;i<=N;i++) a[i].h=read(); for(int i=1;i<=N;i++) a[i].t=read(),a[i].ID=i; sort(a+1,a+N+1); for(int i=1;i<=N;i++) { now.h=a[i].h-a[i].t; if(a[i].t) { int posmax=upper_bound(a+1,a+N+1,now)-a-1; if(posmax) a[i].ans=BIT::Sum(posmax)/posmax+1; else a[i].ans=1; } else { int posmin=lower_bound(a+1,a+N+1,now)-a-1; int posmax=upper_bound(a+1,a+N+1,now)-a-1; a[i].ans=(double)(posmax+BIT::Sum(posmin))/posmin; } BIT::PointChange(i,a[i].ans); } sort(a+1,a+N+1,comp); for(int i=1;i<=N;i++) { if(a[i].ans>=-INF&&a[i].ans<=INF) printf("%.4lf ",a[i].ans); else printf("0.0000 "); } return 0; }

清北集訓Day1T3 LYK loves jumping