題目大意:
就是在不同時間放入和取出小球。算出每個小球生存時間的期望
如果直接用遞歸算會超時。。。這裏可以算出生存時間是是一個線性函數。展開之後就可以發現有O(n)的方法解決。
代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
#include <algorithm>
#define REP(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
struct EVENT{
int time;
int num;
}a[100010],b[100010];
double l[100010],x[100010];
int main()
{
int num;
int n;
char c;
int t;
int na,nb;
na=1;nb=1;num=0;
cin>>n;
getchar();
REP(i,1,2*n)
{
cin>>c;
cin>>t;
if(c=='+'){
num++;
a[na].time=t;
a[na].num=num;
na++;
}
else{
b[nb].time=t;
b[nb].num=num;
num--;
nb++;
}
}
for(int i=n;i>=1;i--){
if(b[i].num==1){
x[i]=1;
l[i]=b[i].time;
}
else{
l[i]=1.0*b[i].time/b[i].num+l[i+1]*(b[i].num-1)/b[i].num;
x[i]=1.0/b[i].num+x[i+1]*(b[i].num-1)/b[i].num;
}
}
int kk=1;
REP(i,1,n){
while(b[kk].time<a[i].time)kk++;
printf("%.10lf\n",l[kk]-x[kk]*a[i].time);
}
}