1400:略
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
const double oo=1e300;
using namespace std;
struct point{int x,y;};
queue <point> q;
int n,m,cnt,tot,ansi,ansj,d[500][500],map[500][500];
int nx[2],ny[2];
double ans;
double bfs(int sx,int sy)
{
int i,tot=0;
point s,ne;
memset(d,127,sizeof(d));d[sx][sy]=0;
s.x=sx,s.y=sy;
q.push(s);
for (;!q.empty();) {
s=q.front();
q.pop();
for (i=0;i<=3;i++) {
ne.x=s.x+dx[i],ne.y=s.y+dy[i];
if (map[ne.x][ne.y]==2 && i==1) ne.x=nx[0],ne.y=ny[0];
if (map[ne.x][ne.y]==3 && i==3) ne.x=nx[1],ne.y=ny[1];
if (ne.y>m) ne.x++,ne.y=1;
if (!ne.y) ne.x--,ne.y=m;
if (d[s.x][s.y]+1<d[ne.x][ne.y] && map[ne.x][ne.y]==1) {
tot+=d[ne.x][ne.y]=d[s.x][s.y]+1;
q.push(ne);
}
}
}
return (double)tot/cnt;
}
int main()
{
double sum;
int i,j,lim;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d%d\n",&tot,&m);cnt=tot;
for (n=1,lim=1;tot;tot--,lim++) {
if (lim>m) ++n,lim=1;
map[n][lim]=1;
}
map[n][lim]=2;nx[0]=1,ny[0]=1;
map[1][0]=3;nx[1]=n,ny[1]=lim-1;
ans=oo,ansi=ansj=0;
for (i=1;i<=n;i++) {
for (j=1;j<=m;j++)
if (map[i][j]) {
sum=bfs(i,j);
if (sum<ans) ans=sum,ansi=i,ansj=j;
}
}
printf("Mean = %.2lf\n",ans);
bfs(ansi,ansj);
for (i=1;i<=n;i++) {
for (j=1;j<=m;j++)
if (map[i][j]==1) printf("%d ",d[i][j]);
printf("\n");
}
return 0;
}
1401:递归解决,每次都是3个完整的+1个缺一个的,在交接处摆L
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int a[1024][1024],d[10];
int n,ans,x,y;
void dfs(int n,int sx,int sy,int fx,int fy)
{
if (1==n) {
++ans;
for (int i=sx;i<=sx+1;i++)
for (int j=sy;j<=sy+1;j++)
if (i!=fx || j!=fy) a[i][j]=ans;
return ;
}
int midx=sx+d[n-1],midy=sy+d[n-1],pd;
if (fx<midx) {
if (fy<midy) pd=0;else pd=1;
}
else {
if (fy<midy) pd=2;else pd=3;
}
++ans;
switch (pd)
{
case 0:
a[midx-1][midy]=ans;a[midx][midy]=ans;a[midx][midy-1]=ans;
dfs(n-1,sx,sy,fx,fy),dfs(n-1,sx,midy,midx-1,midy);
dfs(n-1,midx,sy,midx,midy-1),dfs(n-1,midx,midy,midx,midy);
break;
case 1:
a[midx-1][midy-1]=ans;a[midx][midy-1]=ans;a[midx][midy]=ans;
dfs(n-1,sx,sy,midx-1,midy-1);dfs(n-1,sx,midy,fx,fy);
dfs(n-1,midx,sy,midx,midy-1);dfs(n-1,midx,midy,midx,midy);
break;
case 2:
a[midx-1][midy-1]=ans;a[midx-1][midy]=ans;a[midx][midy]=ans;
dfs(n-1,sx,sy,midx-1,midy-1);dfs(n-1,sx,midy,midx-1,midy);
dfs(n-1,midx,sy,fx,fy);dfs(n-1,midx,midy,midx,midy);
break;
case 3:
a[midx-1][midy]=ans;a[midx-1][midy-1]=ans;a[midx][midy-1]=ans;
dfs(n-1,sx,sy,midx-1,midy-1);dfs(n-1,sx,midy,midx-1,midy);
dfs(n-1,midx,sy,midx,midy-1);dfs(n-1,midx,midy,fx,fy);
break;
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d\n",&n);
d[0]=1;
for (int i=1;i<=n;i++) d[i]=d[i-1]<<1;
scanf("%d%d\n",&x,&y);
memset(a,0,sizeof(a));
ans=0;
dfs(n,1,1,x,y);
for (int i=1;i<=d[n];i++) {
for (int j=1;j<=d[n];j++) printf("%d ",a[i][j]);
printf("\n");
}
return 0;
}
1402:略
#include <cstdio>
#include <iostream>
#include <cstdlib>
const long long maxl=10000000000000LL;
using namespace std;
int i,n;
long long f[100][2];
long long ans[2];
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d\n",&n);
ans[0]=n*(n-1);ans[1]=0;
f[n-1][0]=n*(n-1);
for (i=n-2;i>=1;i--) {
f[i][0]=f[i+1][0]*i;
f[i][1]=f[i+1][1]*i;
f[i][1]+=f[i][0]/maxl;f[i][0]%=maxl;
ans[0]+=f[i][0],ans[1]+=f[i][1];
ans[1]+=ans[0]/maxl;ans[0]%=maxl;
}
if (ans[1]) printf("%lld%013lld\n",ans[1],ans[0]);
else printf("%lld\n",ans[0]);
return 0;
}
1403:直接用堆
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int v[200000],u[200000],w[200000],t[200000],l[200000],r[200000];
int ans,w_time,n,e;
bool cmp(int i,int j) {return t[i]>t[j];}
bool cmp1(int i,int j){return v[i]<v[j];}
int merge(int x,int y)
{
if (!x) return y;
if (!y) return x;
if (w[x]<w[y]) e=x,x=y,y=e;
r[x]=merge(r[x],y);
e=l[x],l[x]=r[x],r[x]=e;
return x;
}
int main()
{
int i,last,mid;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d\n",&n);
for (i=1;i<=n;i++)
scanf("%d%d\n",&t[i],&w[i]);
for (i=1;i<=n;i++) u[i]=i;
sort(u+1,u+n+1,cmp);
mid=ans=0,last=t[u[1]];
for (i=1;i<=n;) {
w_time=t[u[i]];
for (;last>w_time && mid;last--) {
v[mid]=last;
ans++;
mid=merge(l[mid],r[mid]);
}
last=w_time;
for (;t[u[i]]==w_time && i<=n;i++) mid=merge(mid,u[i]);
}
for (;last && mid;last--) {
v[mid]=last;
ans++;
mid=merge(l[mid],r[mid]);
}
printf("%d\n",ans);
sort(u+1,u+n+1,cmp1);
for (i=1;i<=n;i++)
if (v[u[i]]) printf("%d ",u[i]);
return 0;
}
1405:预处理每个点的最大半径,n^2枚举+分类讨论,如果两圆可相交,通过求导发现一定最大化某一半径
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define sqr(x) (x)*(x)
const double pi=3.14159265357,eps=1e-7;
using namespace std;
struct point{double x,y;}a[2000];
double d[1050][1050],f[2000],ans,ri,rj,sum;
int n,i,j;
double dist(point e,point r)
{
return sqrt(sqr(e.x-r.x)+sqr(e.y-r.y));
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d\n",&n);
for (i=1;i<=n;i++) scanf("%lf%lf\n",&a[i].x,&a[i].y);
memset(f,127,sizeof(f));
for (i=1;i<=n;i++)
for (j=i+1;j<=n;j++) {
d[j][i]=d[i][j]=dist(a[i],a[j]);
f[i]=min(f[i],d[i][j]);
f[j]=min(f[j],d[j][i]);
}
ans=0;
for (i=1;i<=n;i++)
for (j=i+1;j<=n;j++) {
ri=min(50.0,f[i]),rj=min(50.0,f[j]);
if (ri-1<-eps || rj-1<-eps) continue;
if (ri+rj>d[i][j]+eps) {
if (d[i][j]-ri>-eps) {
if (d[i][j]-ri-1>-eps) sum=pi*ri*ri+pi*sqr(d[i][j]-ri),ans=max(ans,sum);
else sum=pi*sqr(d[i][j]-1)+pi,ans=max(ans,sum);
}
if (d[i][j]-rj>-eps) {
if (d[i][j]-rj-1>-eps) sum=pi*rj*rj+pi*sqr(d[i][j]-rj),ans=max(ans,sum);
else sum=pi*sqr(d[i][j]-1)+pi,ans=max(ans,sum);
}
}
else ans=max(ans,pi*ri*ri+pi*rj*rj);
}
printf("%.4lf\n",ans);
return 0;
}
1407:重要性质10^(n-1)%2^n==2^(n-1),我们当前得到了n位正整数的解a[n]
a[n]%2^(n+1)==0或2^n
a[n+1]=10^n+a[n]或2*10^n+a[n]
如果a[n]%2^(n+1)==0,那么2*10^n%2^(n+1)==0
如果a[n]%2^(n+1)==2^n,那么10^n%2^(n+1)==2^n
所以分类讨论即可递推出解
1502:推公式
#include <cstdio>
#include <cstdlib>
#include <cstring>
long long n;
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%lld\n",&n);
printf("%lld\n",n*(n+1)*(n+2)/2);
return 0;
}
1503:一元五次方程求解,递归求导,二分零点
wa的要疯了,不知道哪跪了
注意及时将解近似于0的时候归0,如果解在两端就不要二分了,以免精度误差
好吧,其实我现在都没过,拍也拍不出,我翻了一下比赛记录,貌似没有哪个队提交低于10次就a了这道题的
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
const long double eps=1e-18;
const long double oo=1e50;
using namespace std;
long double ans[10][100];
long double a[6];
int n,len[10];
long double fgm(long double x,int e)
{
long double ans=1;
for (int i=1;i<=e;i++) ans*=x;
return ans;
}
long double f(long double x,long double a[6],int e)
{
long double ans=0;
for (int i=0;i<=e;i++) ans+=a[i]*fgm(x,e-i);
return ans;
}
bool equ(long double fy2) {return -eps<fy2 && fy2<eps;}
long double search(long double l,long double r,long double fy1,long double fy2,long double a[6],int e)
{
long double f2,f3,mid;
if (equ(fy1)) return l;
if (equ(fy2)) return r;
f2=fy2;
for (;(r-l)>eps;) {
mid=(l+r)/2;
f3=f(mid,a,e);
if (equ(f3)) return mid;
// printf("%.20lf %lf %.20lf %.20lf\n",(double)mid,(double)f3,(double)l,(double)r);
if (f3*f2<eps) l=mid;else r=mid;
}
return l;
}
void dfs(int e,long double a[6])
{
if (1==e) {
ans[e][++len[e]]=-a[1]/a[0];
if (equ(a[1]/a[0])) ans[e][1]=0;
return ;
}
int i;
long double fy1,fy2;
long double b[6];
for (i=0;i<=e-1;i++) b[i]=a[i]*(e-i);
dfs(e-1,b);
if (len[e-1]) {
fy1=f(-oo,a,e);
fy2=f(ans[e-1][1],a,e);
if (fy1*fy2<eps || equ(fy2)) ans[e][++len[e]]=search(-oo,ans[e-1][1],fy1,fy2,a,e);
for (i=2;i<=len[e-1];i++) {
fy1=fy2;
fy2=f(ans[e-1][i],a,e);
if (fy1*fy2<eps || equ(fy2) || equ(fy1)) ans[e][++len[e]]=search(ans[e-1][i-1],ans[e-1][i],fy1,fy2,a,e);
}
fy1=fy2;
fy2=f(oo,a,e);
if (fy1*fy2<eps || equ(fy1)) ans[e][++len[e]]=search(ans[e-1][len[e-1]],oo,fy1,fy2,a,e);
}
else {
fy1=f(-oo,a,e);
fy2=f(oo,a,e);
if (fy1*fy2<eps) ans[e][++len[e]]=search(-oo,oo,fy1,fy2,a,e);
}
for (i=1;i<=len[e];i++) if (equ(ans[e][i])) ans[e][i]=0;
}
int main()
{
int i;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d\n",&n);
for (i=0;i<=n;i++) {
double x;
scanf("%lf\n",&x);
a[i]=x;
}
dfs(n,a);
for (i=1;i<=len[n];i++) printf("%.6lf\n",(double)ans[n][i]);
return 0;
}
1504:voronoi图?算了吧。。。枚举每个点,求出半平面与圆作交,再在圆上按极角跑一遍点事件,直接用atan2没精度问题
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <ctime>
const double eps=1e-9,pi=3.14159265357;
using namespace std;
#define sqr(x) ((x)*(x))
#define equ(x) ((-eps<x) && (x<eps))
struct point
{
double x,y,z,_;
int w;
}st[5000],a[5000],t;
int k,u[5000],tit[5000],w[5000];
double R;
bool cmp(point i,point j) {return i.w>j.w;}
void cross(point e,point r,point &p)
{
p.x=e.y*r.z-e.z*r.y;
p.y=e.z*r.x-e.x*r.z;
p.z=e.x*r.y-e.y*r.x;
}
void middle(point e,point r,point &p) {p.x=(e.x+r.x)/2,p.y=(e.y+r.y)/2,p.z=1;}
void direct(point e,point l,point &p)
{
p.x=e.x+l.x;
p.y=e.y+l.y;
p.z=1;
}
void orange(double a,double b,double c,double &x1,double &x2)
{
double delt=sqrt(sqr(b)-4*a*c);
x1=(-b+delt)/(a+a);
x2=(-b-delt)/(a+a);
}
void line_round(point l,point &p,point &q)
{
double k,b,A,B,C;
p.w=q.w=0;
p.z=q.z=1;
if (equ(l.y)) {
p.x=q.x=-l.z/l.x;
if (p.x-R>eps) return ;
p.y=sqrt(R*R-p.x*p.x+eps);
q.y=-p.y;
p.w=q.w=1;
}
else {
k=-l.x/l.y,b=-l.z/l.y;
A=(sqr(k)+1),B=2*k*b,C=sqr(b)-R*R;
orange(A,B,C,p.x,q.x);
p.y=k*p.x+b;
q.y=k*q.x+b;
p.w=q.w=1;
}
}
double cr(point e,point r) {return e.x*r.y-e.y*r.x;}
bool cmp1(int i,int j)
{
return st[i]._<st[j]._;
if (fabs(st[i]._-st[j]._)>pi/2) return st[i]._<st[j]._;
double sum=cr(st[i],st[j]);
if (sum>eps) return 1;
return 0;
}
bool cmp2(int i,int j)
{
if (fabs(st[i]._-st[j]._)>eps) return st[i]._<st[j]._;
return w[i]<w[j];
if (fabs(st[i]._-st[j]._)>pi/2) return st[i]._<st[j]._;
double sum=cr(st[i],st[j]);
if (sum>eps) return 1;
if (sum<-eps) return 0;
return w[i]<w[j];
}
int check(int si,point &t)
{
point s,e,r,l;
int tot,i,flag;
s=a[si];
tot=0;
for (i=1;i<=k;i++) {
if (si==i) continue;
cross(s,a[i],l);
middle(s,a[i],e);
direct(e,l,r);
cross(e,r,l);
line_round(l,e,r);
if (e.w) st[++tot]=e;
if (r.w) st[++tot]=r;
tit[tot-1]=tot,tit[tot]=tot-1;
}
for (i=1;i<=tot;i++) u[i]=i;
for (i=1;i<=tot;i++) st[i]._=atan2(st[i].y,st[i].x);
// printf("%d\n",clock());
sort(u+1,u+tot+1,cmp1);
// printf("%d\n",clock());
memset(w,0,sizeof(w));
for (i=1;i<=tot;i++) {
if (w[u[i]]) continue;
e=st[u[i]],r=st[tit[u[i]]];
point p,q;
p.x=r.x-e.x,p.y=r.y-e.y;
q.x=s.x-e.x,q.y=s.y-e.y;
double sum=cr(p,q);
if (sum>eps) w[u[i]]=1,w[tit[u[i]]]=-1;
else {
w[u[i]]=-1;st[u[i]]._+=2*pi;
w[tit[u[i]]]=1;
}
}
int sum=tot;
for (i=1;i<=sum;i++)
if (st[i]._<pi) st[++tot]=st[i],st[tot]._+=2*pi,w[tot]=w[i];
for (i=1;i<=tot;i++) u[i]=i;
// printf("%d\n",clock());
sort(u+1,u+tot+1,cmp2);
// printf("%d\n",clock());
flag=0;
for (i=1;i<=tot;i++) {
if (i!=1 && !flag) {
t=st[u[i]];
// printf("%d %d\n\n",clock(),tot);
return 1;
}
flag+=w[u[i]];
}
// printf("%d %d\n\n",clock(),tot);
return 0;
}
int main()
{
int i;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
double rR;
scanf("%lf%d\n",&rR,&k);
R=rR;
for (i=1;i<=k;i++) {
double x,y;
scanf("%lf%lf%d\n",&x,&y,&a[i].w),a[i].z=1;
a[i].x=x,a[i].y=y;
}
sort(a+1,a+k+1,cmp);
for (i=1;i<=k;i++)
if (check(i,t)) break;
printf("%.8lf %.8lf\n",(double)t.x,(double)t.y);
// printf("%d\n",a[i].w);
return 0;
}
1508:记f[i][j]为从i开始的第j段,从前往后是否可行,用k个单调指针可以再n^2时间dp出来,并且可以得到h[i][j]为转移到此状态最前的i',再返着dp出F[i][j]为从后之前是否可行,同样是n^2的时间,接着如果f[i][j]==F[i][j]==1的话,那么这个状态肯定是存在在解中的,因此[i,i+a[j]-1]都可以为1,然后[h[i][j]+a[j-1],i-1]都可以为0,用点事件跑一遍即可。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int i,j,k,p,L,e,flag;
int a[1000],s[1000];
bool f[500][500],F[500][500],t[500][2];
int h[500][500],g[1000],add[1000],del[1000];
char ch[1000];
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d%d\n",&L,&k);
for (i=1;i<=k;i++) scanf("%d",&a[i]),s[i]=s[i-1]+a[i];scanf("\n");
scanf("%s\n",ch+1);
memset(f,0,sizeof(f));
memset(g,61,sizeof(g));
memset(F,0,sizeof(F));
f[0][0]=1,g[0]=0;
for (i=1;i<=L;i++) {
for (p=i;p<=L && ch[p]!='.';p++) ;
for (j=1;j<=k;j++) {
if (i<=s[j-1]) break;
if (g[j-1]+a[j-1]-1<i-1 && i+a[j]-1<p && ch[i+a[j]]!='X' && ch[i]!='.') f[i][j]=1,h[i][j]=g[j-1];
}
for (j=1;j<=k;j++) {
if (ch[i]=='X') {
for (;g[j]<=i && (!f[g[j]][j] || g[j]+a[j]-1<i);g[j]++) ;
if (g[j]>i) g[j]=g[k+1];
}
if (f[i][j]) g[j]=min(g[j],i);
}
if (ch[i]=='X') g[0]=g[k+1];
}
for (p=L;p>=1 && ch[p]!='X';p--) ;
for (i=L;i>=1;i--)
if (i+a[k]-1>=p) F[i][k]=f[i][k];
for (j=k-1;j>=1;j--) {
for (p=L;p>=1 && (!f[p][j+1] || !F[p][j+1]);p--) ;
for (i=L;i>=1;i--) {
if (i+a[j]-1<p-1 && f[i][j]) F[i][j]=1;
if (ch[i+a[j]-1]=='X') {
p=min(p,i+a[j]-1);
for (;p>=1 && (!f[p][j+1] || !F[p][j+1]);p--) ;
}
}
}
flag=0;
for (i=1;i<=L;i++)
for (j=1;j<=k;j++)
if (f[i][j] && F[i][j]) add[i]++,del[i+a[j]-1]--,flag++;
if (!flag) {
if (k) {printf("Impossible\n");return 0;}
for (i=1;i<=L;i++)
if (ch[i]=='X') {printf("Impossible\n");return 0;}
for (i=1;i<=L;i++) printf(".");
return 0;
}
flag=0;
for (i=1;i<=L;i++) {
flag+=add[i];
if (flag>0) t[i][1]=1;
flag+=del[i];
}
memset(add,0,sizeof(add));
memset(del,0,sizeof(del));
for (i=1;i<=L;i++)
for (j=1;j<=k;j++)
if (f[i][j] && F[i][j]) {
add[h[i][j]+a[j-1]]++,del[i-1]--;
// if (!h[i][j] && i!=1) add[1]++;
if (j==k)
add[i+a[j]]++,del[L]--;
}
flag=0;
for (i=0;i<=L;i++) {
flag+=add[i];
if (flag>0) t[i][0]=1;
flag+=del[i];
}
for (i=1;i<=L;i++) {
if (t[i][0] && t[i][1]) printf("?");
else if (t[i][0]) printf(".");
else printf("X");
}
return 0;
}
1510:一个数出现次数超过n/2,那么我把两两不相同的数去掉,最后留下来的数一定是我们要求的,所以直接用计数器扫一遍即可
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int n,i,x,sum,tmp;
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d\n",&n);
tmp=sum=0;
for (i=1;i<=n;i++) {
scanf("%d\n",&x);
if (sum) {
if (x!=tmp) sum--;
else sum++;
}
else tmp=x,sum=1;
if (sum>n/2) break;
}
printf("%d\n",tmp);
return 0;
}
1565:排序后,A必定打B,B之后是A的话,B一定打A,如果中间有C的话,还需要讨论一下,C肯定不会第一个被其他两人打,因此要打就打命中率最大的,同时打不打要讨论
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
double a[4],b[4],sum1,sum2,sum3,tot1,tot2,tot3,cnt1,cnt2,cnt3,e,p;
int flag;
int main()
{
freopen("i.txt","r",stdin);
freopen("o.txt","w",stdout);
scanf("%lf%lf%lf\n",&a[1],&a[2],&a[3]);
if (a[2]<a[3]) flag=1,e=a[2],a[2]=a[3],a[3]=e;
//ABC ACB
p=2.0/6;
b[1]+=(1-a[3])*p;b[3]+=a[3]*p;
//BAC
p=1.0/6;
b[2]+=p*a[2]*(1-a[3]/(1-(1-a[3])*(1-a[2])));
b[3]+=p*a[2]*(a[3]/(1-(1-a[3])*(1-a[2])));
b[1]+=p*(1-a[2])*(1-a[3]);
b[3]+=p*(1-a[2])*a[3];
//CAB
sum2=p*a[3]*(a[2]/(1-(1-a[3])*(1-a[2])));
sum3=p*a[3]*(1-a[2]/(1-(1-a[3])*(1-a[2])))+p*(1-a[3])*a[3];
sum1=p*(1-a[3])*(1-a[3]);
tot2=0;
tot3=p*a[3];
tot1=p*(1-a[3]);
if (tot3>sum3) b[1]+=tot1,b[2]+=tot2,b[3]+=tot3;
else b[1]+=sum1,b[2]+=sum2,b[3]+=sum3;
//CBA
sum2=p*a[3]*(a[2]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[3])*a[2]*(1-a[3]/(1-(1-a[3])*(1-a[2])));
sum3=p*a[3]*(1-a[2]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[3])*a[2]*(a[3]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[3])*(1-a[2])*a[3];
sum1=p*(1-a[3])*(1-a[2])*(1-a[3]);
tot2=p*a[2]*(1-a[3]/(1-(1-a[3])*(1-a[2])));
tot3=p*a[2]*(a[3]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[2])*a[3];
tot1=p*(1-a[2])*(1-a[3]);
if (tot3>sum3) b[1]+=tot1,b[2]+=tot2,b[3]+=tot3;
else b[1]+=sum1,b[2]+=sum2,b[3]+=sum3;
//BCA
sum2=p*a[2]*(1-a[3]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[2])*a[3]*(a[2]/(1-(1-a[3])*(1-a[2])));
sum3=p*a[2]*(a[3]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[2])*a[3]*(1-a[2]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[2])*(1-a[3])*a[3];
sum1=p*(1-a[2])*(1-a[3])*(1-a[3]);
tot2=p*a[2]*(1-a[3]/(1-(1-a[3])*(1-a[2])));
tot3=p*a[2]*(a[3]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[2])*a[3];
tot1=p*(1-a[2])*(1-a[3]);
if (tot3>sum3) cnt1=tot1,cnt2=tot2,cnt3=tot3;
else cnt1=sum1,cnt2=sum2,cnt3=sum3;
sum2=p*a[3]*(a[2]/(1-(1-a[3])*(1-a[2])));
sum3=p*a[3]*(1-a[2]/(1-(1-a[3])*(1-a[2]))) + p*(1-a[3])*a[3];
sum1=p*(1-a[3])*(1-a[3]);
tot2=0;
tot3=a[3];
tot1=1-a[3];
if (tot3>sum3) sum1=tot1,sum2=tot2,sum3=tot3;
if (cnt2>sum2) b[1]+=cnt1,b[2]+=cnt2,b[3]+=cnt3;
else b[1]+=sum1,b[2]+=sum2,b[3]+=sum3;
if (flag) printf("%lf %lf %lf\n",b[1],b[3],b[2]);
else printf("%lf %lf %lf\n",b[1],b[2],b[3]);
}