JSOI2015 Round2 Day1
来源:互联网 发布:oracle sql语句 编辑:程序博客网 时间:2024/05/01 07:51
感觉还是好懒啊,这样看来一轮省选前肯定更不完辣。
T1:
T1就是一个裸的树状数组啊,预处理出来每位女士选择每位男士的可能行,然后按照女士为第一关键字,男士为第二关键字,排个序。扫描一遍,每次查询一下比当前男士大的和,再把这位女士选择这位男士的可能性插进去,总之没什么难度。
想要求出每位女士选择每位男士的可能性有两种方法,一是无穷数列求和,假设某位女士一共有n位可选择的男士,当前正在考虑的排名第m,那么就是:
这个数列显然收敛,求个和就好辣。
也可以这么想,第一轮成功牵手的为q=1-(1-p)^n,其中选择第i位男士的概率为q2=p*(1-p)^(i-1),答案就是q2/q。
貌似精度有问题,不过有SPJ(好像?)
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cstdlib>#define maxn 500010using namespace std;const double eps=1e-6;struct Node{int x,y;double dis;bool operator<(const Node &t)const{return x<t.x||(x==t.x&&y<t.y);}}A[maxn];bool cmp2(Node a,Node b){return a.x<b.x||(a.x==b.x&&a.y>b.y);}int n,m;double p;double exp[maxn],sm[maxn];double c[maxn];void add(int x,double y){for(;x<=n;x+=x&(-x))c[x]+=y;}double query(int x){double ans=0;for(;x;x-=x&(-x))ans+=c[x];return ans;}void Work(){double ans=0;for(int l=1,r=1;l<=m;l=r+1){while(A[r+1].x==A[l].x)r++;for(int j=1;j<=r-l+1;j++)A[l+j-1].dis=exp[j-1]*p/(1-exp[r-l+1]);}//sort(A+1,A+m+1,cmp2);for(int i=1;i<=m;i++){ans+=A[i].dis*(query(n)-query(A[i].y));add(A[i].y,A[i].dis);}printf("%.2lf\n",ans);}void Init(){scanf("%d%d",&n,&m);scanf("%lf",&p);exp[0]=1;for(int i=1;i<=m;i++)exp[i]=exp[i-1]*(1-p);for(int i=1;i<=m;i++)sm[i]=sm[i-1]+exp[i];for(int i=1;i<=m;i++)scanf("%d%d",&A[i].x,&A[i].y);sort(A+1,A+m+1);}int main(){freopen("cross.in","r",stdin);freopen("cross.out","w",stdout);Init();Work();return 0;}
T2:
一道贪心题,首先注意到最小化目标可以转化为最大化目标。我们把最小化空隙乘权值,转化为最大化每个的外径乘权值,这样子就可以贪心辣。
把外径从大到小排个序,每次考虑一个外径,选择一个可以选择的(内径严格大于它的)最大权值,然后删去这个内径,需要离散化一下。
正确性显然,若一个可以选择的较大权值y给了较大半径b,较小权值x给了较小半径a,那么by+ax>ay+bx可以有柯西不等式证明,交换不会取得更大的优势。
每次操作可以用线段树优化
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cstdlib>#define LL long long#define maxn 200010using namespace std;struct Node{int x,y,k;}A[maxn];struct Hash{int x,tp,id,V;bool operator<(const Hash &t)const{if(x!=t.x)return x<t.x;if(tp!=t.tp)return tp<t.tp;return id<t.id;}Hash(int x=0,int tp=0,int id=0,int V=0):x(x),tp(tp),id(id),V(V) {}}hash[maxn<<1];struct Tree{int l,r,mx;}T[maxn<<3];void build(int i,int l,int r){int M=l+r>>1;T[i].l=l;T[i].r=r;if(l==r){T[i].mx=hash[l].V;return;}build(i<<1,l,M);build(i<<1|1,M+1,r);T[i].mx=max(T[i<<1].mx,T[i<<1|1].mx);}int query(int i,int l,int r){int M=T[i].l+T[i].r>>1;if(l<=T[i].l&&r>=T[i].r)return T[i].mx;if(r<=M)return query(i<<1,l,r);if(l>M)return query(i<<1|1,l,r);return max(query(i<<1,l,r),query(i<<1|1,l,r));}void update(int i,int x,int t){int M=T[i].l+T[i].r>>1;if(T[i].l==T[i].r){T[i].mx=0;return;}if(T[i<<1|1].mx>=t)update(i<<1|1,x,t);else update(i<<1,x,t);T[i].mx=max(T[i<<1].mx,T[i<<1|1].mx);}int n,tot;void Work(){LL ans=0;for(int i=1;i<=n;i++)ans+=1LL*A[i].k*A[i].y;for(int i=tot;i;i--)if(hash[i].tp){int t=query(1,i+1,tot+1);//cout<<hash[i].x<<' '<<t<<endl;ans-=1LL*hash[i].x*t;update(1,i+1,t);}printf("%I64d\n",ans);}void Init(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d%d",&A[i].x,&A[i].y,&A[i].k);hash[++tot]=Hash(A[i].x,1,i,0);hash[++tot]=Hash(A[i].y,0,i,A[i].k);}sort(hash+1,hash+tot+1);build(1,1,tot+1);}int main(){freopen("doll.in","r",stdin);freopen("doll.out","w",stdout);Init();Work();return 0;}
T3:
T3我也没写啦啦啦。
我们来讲讲部分分吧,
20分部分分:
考虑左右端点,受三个值的影响,投影布的左右端点,光源角度,光线能跑的距离,三者搞一搞,搞出来一个范围,就好了,不能更水(坑)。
double r=tx;r=min(r,sqrt(max(len*len-ty*ty,0.0)));r=min(r,ty*tan(rnd(ang/2)));double l=sx;l=max(l,-sqrt(max(len*len-ty*ty,0.0)));l=max(l,-ty*tan(rnd(ang/2)));printf("%.4lf\n",(r-l)/(tx-sx));
40分;
为了这20分。。。
首先还是先求出左右端点,用的是上一个部分分的方法。
然后对于每一个墙,,求出左右端点的极角,映射到投影布所在的平面上,期间很多注意点。
比如不能向下映射,可能产生无穷,比如内区间还是外区间,反正这20分就不好拿辣。
某司机挂了20分,手动蜡烛。
void get_dang(int i){double r1,r2;r1=atan2(A[i].y1,A[i].x1);r2=atan2(A[i].y2,A[i].x2);if(r1>r2)swap(r1,r2);if(r1<-pi/2&&r2>pi/2)swap(r1,r2);if(r1<0&&r2<0)return;if(r1<0&&r2>0)r1=1e-5;if(r1>0&&r2<0)r2=pi-1e-5;double l=sy*tan(pi/2-r2),r=sy*tan(pi/2-r1);D[++cnt].l=l;D[cnt].r=r;}void Plan2(){double r=tx;r=min(r,sqrt(max(len*len-ty*ty,0.0)));r=min(r,ty*tan(rnd(ang/2)));double l=sx;l=max(l,-sqrt(max(len*len-ty*ty,0.0)));l=max(l,-ty*tan(rnd(ang/2)));for(int i=1;i<=n;i++)get_dang(i);for(int i=1;i<=cnt;i++)D[i].l=max(D[i].l,l),D[i].l=min(D[i].l,r),D[i].r=max(D[i].r,l),D[i].r=min(D[i].r,r);sort(D+1,D+cnt+1);double t=0,lst=-1e10;for(int i=1;i<=cnt;i++){if(D[i].l>lst)t+=D[i].r-D[i].l;else t+=D[i].r-lst;lst=D[i].r;}printf("%.4lf\n",(r-l-t)/(tx-sx));}
以下纯属口胡:
60pts,处理一面镜子就好辣
100pts:
我们将角度分成极小的一份份,每一份射出一条,记录他的经过反射和吸收的路线,如果相邻的两条光线经过的路径完全一样,我们就认为这一段区间内都完全一样,否则继续二分。
复杂度玄学,可以通过所有测试点。
- JSOI2015 Round2 Day1
- JSOI2015 Round2 Day2题解
- JSOI2015 day1
- SDOI2014 Round2 Day1
- SDOI2015 Round2 Day1总结
- JSOI2015 Round3 Day1
- 省队集训Round2 DAY1
- JSOI2015
- Round2 - Probability
- [弱校胡策Round2]
- 【JSOI2015】非诚勿扰
- Day1
- day1
- day1
- day1
- day1
- day1
- day1
- java classLoader体系结构使用详解
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
- 鹅厂2016实习生招聘试题2
- C语言宏定义和宏定义函数
- 程序员必知的8大排序(三)-------冒泡排序,快速排序(java实现)
- JSOI2015 Round2 Day1
- android设计模式应用--中介者模式
- mysql:sql-mode
- android基础点击事件的四种写法和数据的存储方式
- Dubbo构建问题
- 程序员必知的8大排序(四)-------归并排序,基数排序(java实现)
- AngularJS路由实例(uiRoute、ngRoute)
- 百思不得姐框架(二)
- 互联网协议入门(1)