这是一个句子测试

12
8
2015
0

Contest20151207滚粗记

听说这是JSOIDay3

膜了贵省的题目,感到不明觉厉。

Orz NiroBC 210

Orz Chrysanthemum 130

Orz drc神犇(SB) 0

T1

看到期望慌了,先吔点东西压压惊。

好吧让窝萌推一下。

对于一个女性,列表中总共有cnt个对象,选中第i个对象的概率:

[tex]\sum\limits_{j = 0}^{ + \infty } {p*{{(1 - p)}^{i + cnt*j - 1}}}[/tex]

显然这是一个等比数列,列出求和公式:

[tex]\frac{{1 - {{(1 - p)}^j}}}{{1 - {{(1 - p)}^{cnt}}}}*p*{(1 - p)^{i - 1}}[/tex]

当j趋向于正无穷时(1-p)j趋向于0,那么公式就变成了:

[tex]\frac{{p*{{(1 - p)}^{i - 1}}}}{{1 - {{(1 - p)}^{cnt}}}}[/tex]

接着只要倒着扫一遍,然后将概率一一插入树状数组并询问就可以辣!

什么我居然丢了这送的40分。

T2

看到题目慌了,这不是NiroBC出的Gold_7穿裙子?

让窝萌来YY一个最小割小费用最大流吧。

哦好像是错的。愉快爆蛋。

我去正解是贪心。。。贪心怎会没有反例

考虑将x0放入x,y0放入y,其中b[x]>b[y],Out[x0]<Out[y0]。

如果把x0放入y,y0放入x(假设x0和y0都是可以放进x和y的)。

ans1=(In[x]-Out[x0])*b[x]+(In[y]-Out[y0])*b[y]

ans2=(In[x]-Out[y0])*b[x]+(In[y]-Out[x0])*b[y]

ans1-ans2=(Out[y0]-Out[x0])*(b[x]-b[y])<0

显然按b排序,取能放下的最大的,一定不存在更优解。

所以贪心好像没有反例。

那么用数据结构维护一下就可以辣!

(窝用二分+线段树O(nlogn2)然而Gold_7用set既快又短。。。)

T3

看到计蒜几何慌了,让我先打个20分压压惊。

诶好像40分也很好拿吖。

诶好像这只是一道码农题+乱搞题。

拒绝做这种恶心题。

【Codes】

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int M=1000010;
int n,m,i,j,x,y,edgenum;
double p,ans;
int head[M],vet[M],next[M],a[M];
double tree[M];
double mi[M];
void addedge(int x,int y){
	vet[++edgenum]=y;
	next[edgenum]=head[x];
	head[x]=edgenum;
}
int lowbit(int x){return x&(-x);}
double query(int x){
	double ans=0;
	while (x){
		ans+=tree[x];
		x-=lowbit(x);
	}
	return ans;
}
void update(int x,double t){
	while (x<=n){
		tree[x]+=t;
		x+=lowbit(x);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	scanf("%lf",&p);
	for (i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		addedge(x,y);
	}
	mi[0]=1;
	for (i=1;i<=n;i++)mi[i]=mi[i-1]*(1-p);
	for (i=n;i>=1;i--){
		int cnt=0;
		for (int e=head[i];e;e=next[e])a[++cnt]=vet[e];
		sort(a+1,a+cnt+1);
		for (j=cnt;j>=1;j--)ans+=p*mi[j-1]/(1-mi[cnt])*query(a[j]-1),update(a[j],p*mi[j-1]/(1-mi[cnt]));
	}
	printf("%.2lf",ans);
}
#include<cstdio>
#include<algorithm>
#include<cstring>
typedef long long ll;
using namespace std;
int n,i,flag;
ll ans;
int tree[500010];
struct shit{ll in;ll out;ll imp;}a[500010];
bool cmp(shit i,shit j){return i.imp>j.imp;}
void update(int x,int l,int r,int p,int cmp){
	tree[p]+=cmp;
	if (l==r)return;
	int mid=l+r>>1;
	if (x<=mid)update(x,l,mid,p<<1,cmp);else update(x,mid+1,r,p<<1|1,cmp);
}
int search(int x,int y,int l,int r,int p){
	if (x==l&&y==r)return tree[p];
	int mid=l+r>>1;
	if (y<=mid)return search(x,y,l,mid,p<<1);
		else if (x>mid) return search(x,y,mid+1,r,p<<1|1);
			else return search(x,mid,l,mid,p<<1)+search(mid+1,y,mid+1,r,p<<1|1);
}
int main(){
	scanf("%d",&n);
	for (i=1;i<=n;i++)scanf("%d%d%d",&a[i].out,&a[i].in,&a[i].imp);
	sort(a+1,a+n+1,cmp);
	for (i=1;i<=n;i++)update(a[i].out,1,10000,1,1);
	for (i=1;i<=n;i++){
		if (a[i].in==1){ans+=a[i].in*a[i].imp;continue;}
		int cnt=0;
		int l=1,r=a[i].in-1;
		while (l+1<r){
			int mid=l+r>>1;
			if (search(mid,a[i].in-1,1,10000,1))l=mid;else r=mid;
		}
		if (search(r,a[i].in-1,1,10000,1))cnt=r;else if (search(l,a[i].in-1,1,10000,1))cnt=l;else ans+=a[i].in*a[i].imp;
		if (cnt)update(cnt,1,10000,1,-1),ans+=(a[i].in-cnt)*a[i].imp;
	}
	printf("%lld\n",ans);
}
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const double pi=3.1415926535;
int n,i,ans,ans1,flag[100];
double stx[100],sty[100],edx[100],edy[100];
double X1,Y1,X2,Y2,ang,len,k;
int check(int x){
	if (stx[x]==edx[x]){if (k*stx[x]>=sty[x]&&k*stx[x]<=edy[x]||k*stx[x]>=edy[x]&&k*stx[x]<=sty[x])return 0;else return 1;}
	double k1=(edy[x]-sty[x])/(edx[x]-stx[x]);
	double b=sty[x]-stx[x]*k1;
	if (k==k1)return 1;
	double xx=b/(k-k1);
	if (xx>=stx[x]&&xx<=edx[x])return 0;else return 1;
}
int main(){
	freopen("light.in","r",stdin);
	freopen("light.out","w",stdout);
	scanf("%d%lf%lf",&n,&ang,&len);
	for (i=1;i<=n;i++){
		scanf("%lf%lf%lf%lf%d",&stx[i],&sty[i],&edx[i],&edy[i],&flag[i]);
		if (stx[i]>edx[i])swap(stx[i],edx[i]),swap(sty[i],edy[i]);
		if (flag[i]==1){printf("Orz\n");return 0;}
	}
	scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2); 
	double shit=X1;
	while (shit<=X2){
		shit=shit+(X2-X1)/1000000;
		if (shit==0)continue;
		ans1++;
		k=Y1/shit;
		for (i=1;i<=n+1;i++)
			if (i==n+1||!check(i))break;
		if (i!=n+1)continue;
		double x=Y1/k;
		if (shit*shit+Y1*Y1<=len*len){
			if (shit<0&&atan(k)+pi/2<=ang/360*pi||shit>0&&pi/2-atan(k)<=ang/360*pi)ans++;
		}
	}
	printf("%.4lf\n",(double)ans/ans1);
}
Category: 蒟蒻的滚粗记 | Tags: | Read Count: 177

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com