【bestcoder #35】AB题解

DZY Loves Balls

Accepts: 371

Submissions: 988

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/65536 K (Java/Others)

问题描述

一个盒子里有n个黑球和m个白球。现在DZY每次随机从盒子里取走一个球,取了n+m次后,刚好取完。DZY用这种奇怪的方法生成了一个随机的01串S[1?(n+m)]。如果DZY第i次取出的球是黑色的,那么S[i]=1,如果是白色的,那么S[i]=0。
DZY现在想知道,‘01‘在S串中出现的期望次数。

输入描述

输入有多组测试数据。 (TestCase≤150)
每行两个整数, n, m(1≤n,m≤12)

输出描述

对于每个测试数据,输出一行答案,格式为p/q(p,q互质)。

输入样例

1 1
2 3

输出样例

1/2
6/5

Hint

Case 1: S=‘01‘ or S=‘10‘, 所以期望次数 = 1/2
Case 2: S=‘00011‘ or S=‘00101‘ or S=‘00110‘ or S=‘01001‘ or S=‘01010‘
or S=‘01100‘ or S=‘10001‘ or S=‘10010‘ or S=‘10100‘ or S=‘11000‘,
所以期望次数 = (1+2+1+2+2+1+1+1+1+0)/10 = 12/10 = 6/5

排列组合。

一共有C(n+m,n)种排列。

01出现的次数:枚举01的位置然后计算其他位置的摆放方案数(n+m-1)*C(n+m-2,n-1)

期望(n+m-1)*C(n+m-2,n-1)/C(n+m,n)=(n*m)/(n+m)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
int main()
{
	int n,m;
    while (scanf("%d%d",&n,&m)!=EOF)
	{
		int k=__gcd(n*m,n+m);
		cout<<n*m/k<<"/"<<(n+m)/k<<endl;
	}
	return 0;
}

DZY Loves Topological Sorting

Accepts: 112

Submissions: 586

Time Limit: 4000/2000 MS (Java/Others)

Memory Limit: 131072/131072 K (Java/Others)

问题描述

一张有向图的拓扑序列是图中点的一个排列,满足对于图中的每条有向边(u→v) 从 u 到 v,都满足u在排列中出现在v之前。
现在,DZY有一张有向无环图(DAG)。你要在最多删去k条边之后,求出字典序最大的拓扑序列。

输入描述

输入有多组数据。 (TestCase≤5)
第一行,三个正整数 n,m,k(1≤n,m≤105,0≤k≤m).
接下来m行,每行两个正整数 u,v(u≠v,1≤u,v≤n), 代表一条有向边(u→v).

输出描述

对于每组测试数据,输出一行字典序最大的拓扑序列。

输入样例

5 5 2
1 2
4 5
2 4
3 4
2 3
3 2 0
1 2
1 3

输出样例

5 3 1 2 4
1 3 2

Hint

数据1. 删除(2->3),(4->5)两条边,可以得到字典序最大的拓扑序列:(5,3,1,2,4).

(思路并不难的一道题,可是我在结束的前15分钟才想出来正解。。写出来了没调对。。)

首先计算出每个点的度数。

使拓扑序最大的数字就是当前度数<=k的最大数字,k-=他的度数,他所连得点度数减1。

然后重复这个过程。

问题就变成了查找<=k的最大数字,在线段树中维护区间最小值,直接二分就可以了。

修改的复杂度是O(mlogn),查询的复杂度是O(nlogn),总复杂度O((m+n)logn)

注意:此题不写读入优化就TLE了。。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define inf 0x3f3f3f3f
using namespace std;
int cnt,tot,h[150005],d[150005],n,m,k;
struct edge
{
	int y,ne;
}e[150005];
struct Segtree
{
	int l,r,m;
}a[500000];
void read(int &tmp)
{
	tmp=0;
	int fu=1;
	char ch=getchar();
	for (;ch<'0'||ch>'9';ch=getchar())
		if (ch=='-') fu=-1;
	for (;ch>='0'&&ch<='9';ch=getchar())
		tmp=tmp*10+ch-'0';
	tmp*=fu;
}
void Addedge(int x,int y)
{
	e[++tot].y=y;
	e[tot].ne=h[x];
	h[x]=tot;
	d[y]++;
}
void P(int x)
{
	if (a[x<<1].m<a[(x<<1)+1].m) a[x].m=a[x<<1].m;
	else a[x].m=a[(x<<1)+1].m;
}
void Build(int x,int l,int r)
{
	a[x].l=l,a[x].r=r;
	if (l==r)
	{
		a[x].m=d[l];
		return;
	}
	int m=(l+r)>>1;
	Build(x<<1,l,m);
	Build((x<<1)+1,m+1,r);
	P(x);
}
int Find(int x,int k)
{
	if (a[x].l==a[x].r)
		return a[x].l;
	if (a[(x<<1)+1].m<=k) return Find((x<<1)+1,k);
	return Find(x<<1,k);
}
void M(int x,int y,int k)
{
	if (a[x].l==a[x].r)
	{
		a[x].m+=k;
		return;
	}
	int m=(a[x].l+a[x].r)>>1;
	if (y<=m) M(x<<1,y,k);
	else M((x<<1)+1,y,k);
	P(x);
}
int main()
{
    while (scanf("%d%d%d",&n,&m,&k)!=EOF)
	{
		tot=0;
		for (int i=1;i<=n;i++)
			d[i]=0,h[i]=0;
		int x,y;
		for (int i=1;i<=m;i++)
		{
			read(x),read(y);
			Addedge(x,y);
		}
		Build(1,1,n);
		for (int i=1;i<=n;i++)
		{
			x=Find(1,k);
			k-=d[x];
			M(1,x,inf);
			d[x]=inf;
			if (i==1) printf("%d",x);
			else printf(" %d",x);
			for (int j=h[x];j;j=e[j].ne)
				if (d[e[j].y]!=inf)
					M(1,e[j].y,-1),d[e[j].y]--;
		}
		printf("\n");
	}
	return 0;
}
时间: 2024-10-22 11:00:39

【bestcoder #35】AB题解的相关文章

BestCoder Round #11 题解集合

1001.Alice and Bob 签到题*1,只要x * 2 == n && y * 2 == m就满足条件. 1 var 2 m, n, x, y : int64; 3 4 begin 5 while not eof do begin 6 readln(m, n, x, y); 7 if (m = 2 * x) and (n = 2 * y) then writeln('YES') else writeln('NO'); 8 end; 9 end. 1002.Bob and math

BestCoder 1st Anniversary ($) 题解

Souvenir 问题描述 今天是BestCoder一周年纪念日. 比赛管理员Soda想要给每个参赛者准备一个纪念品. 商店里纪念品的单价是p元, 同时也可以花q元购买纪念品套装, 一个套装里有m个纪念品. 今天总共有n个参赛者, Soda想要知道最少需要花多少钱才可以给每个人都准备一个纪念品. 输入描述 输入有多组数据. 第一行有一个整数T (1≤T≤105), 表示测试数据组数. 然后对于每组数据: 一行包含4个整数 n,m,p,q (1≤n,m,p,q≤104). 输出描述 对于每组数据输

【codeforces #275(div1)】AB题解

A. Diverse Permutation time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Permutation p is an ordered set of integers p1,???p2,???...,???pn, consisting of n distinct positive integers not larg

【UOJ #6】AB题解

#74 破解密码 首先容易得出第i位编号为x的字母的公式: (26^n -1)*x=26*h[i]-h[i+1] 我们可以先求出(26^n -1)%mod的逆元,乘到右边去即可. 可是,这样做只有50分! (26^n -1)%mod=0的时候没有逆元!!也就是说这种情况下x为任何数都可以,而这种算法会导致全部输出a,h[]全部都是0了,可能与读入的h不符. 因此这种情况的做法是:求出h[1]用26进制表示的n位数,直接输出就是答案了.因为他满足h[1],后面的必然满足. <span style=

【codeforces #282(div 1)】AB题解

A. Treasure time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Malek has recently found a treasure map. While he was looking for a treasure he found a locked door. There was a string s writte

codeforces1c给出三点求面积

题意:有一个正n边形的斗兽场,现存有3根柱子,柱子位于正n边形的任意3个节点上.求出正n边形的最小面积. 1 #include <iostream> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <math.h>//采用三角函数大部分使用弧度 5 #include <utility> 6 #include <algorithm> 7 using namespace std;

hdu 5059 Help him

Help him Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 480    Accepted Submission(s): 119 Problem Description As you know, when you want to hack someone's program, you must submit your test d

【线段树】Bzoj1798 [AHOI2009] 维护序列

Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. Input 第一行两个整数N和P(1≤P≤1000000000).第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N).第三行有一个整

hdu 5060 War

War Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 98    Accepted Submission(s): 28 Special Judge Problem Description Long long ago there are two countrys in the universe. Each country haves i