Skip to main content
  1. Posts/

bzoj 1607 [Usaco2008 Dec]Patting Heads 轻拍牛头 (筛法)

·1 min
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

http://www.lydsy.com/JudgeOnline/problem.php?id=1607

题意:n个数,求对于每个数来说,其他n-1个数中是它约数的数的个数。

思路:类似筛法,从小到大处理,数i对其所有倍数的数的答案有cnt[i]的贡献 。最后记得把自己是自己的约数的情况减掉。

 1/* ***********************************************
 2Author :111qqz
 3Created Time :2016年02月28日 星期日 01时06分35秒
 4File Name :code/bzoj/1607.cpp
 5************************************************ */
 6
 7#include <cstdio>
 8#include <cstring>
 9#include <iostream>
10#include <algorithm>
11#include <vector>
12#include <queue>
13#include <set>
14#include <map>
15#include <string>
16#include <cmath>
17#include <cstdlib>
18#include <ctime>
19#define fst first
20#define sec second
21#define lson l,m,rt<<1
22#define rson m+1,r,rt<<1|1
23#define ms(a,x) memset(a,x,sizeof(a))
24typedef long long LL;
25#define pi pair < int ,int >
26#define MP make_pair
27
28using namespace std;
29const double eps = 1E-8;
30const int dx4[4]={1,0,0,-1};
31const int dy4[4]={0,-1,1,0};
32const int inf = 0x3f3f3f3f;
33const int N=1E5+7;
34int n;
35int a[N];
36int cnt[N*10];
37int ans[N*10];
38int main()
39{
40	#ifndef  ONLINE_JUDGE
41//	freopen("code/in.txt","r",stdin);
42  #endif
43
44	ms(cnt,0);
45
46	cin>>n;
47	int mx = -1;
48	for ( int i = 0 ; i < n ; i++)
49	{
50	    scanf("%d",&a[i]);
51	    cnt[a[i]]++;
52	    mx = max(mx,a[i]);
53	}
54
55	for ( int i = 1 ; i <= mx; i++)
56	    if (cnt[i])                       //类似筛法,对所有倍数都有贡献
57		for ( int j = 1 ; j*i <= mx ; j++)
58		    ans[j*i]+=cnt[i];
59
60	for ( int i = 0  ;i < n ; i++)
61	    printf("%d\n",ans[a[i]]-1);//减去自己是自己约数的情况
62
63
64
65
66
67  #ifndef ONLINE_JUDGE
68  fclose(stdin);
69  #endif
70    return 0;
71}

Related

codeforces #341 div 2 D. Rat Kwesh and Cheese

·3 mins
http://codeforces.com/contest/621/problem/D # 题意:给出12个式子,问哪个最大。 思路:主要记住两个。一个是比较指数形式的数一个常用办法是取对数,同时要考虑是否能取对数,分情况讨论对于不能取对数的情况经过变换去取对数。第二个是取了两次对数后比较时候的最大值可能是小于0的。所以初始时置于0不够小。官方题解说得很清楚。

codeforces #342 div 2 A. Guest From the Past

·1 min
http://codeforces.com/contest/625/problem/A 题意:有n块钱,塑料瓶饮料a元一瓶,玻璃瓶饮料b元一瓶,退还玻璃瓶可以得到c元。问最多能买多少瓶饮料。 思路:贪心。如果塑料瓶比玻璃瓶的实际价格便宜,那么一定买塑料瓶的,否则先买玻璃瓶,再用塑料瓶填。注意一些边界的判断。。

codeforces 107 B. Basketball Team

·2 mins
http://codeforces.com/problemset/problem/107/B 题意:有m个部门,每个部分s[i]个人,HW在第h部门,现在要从这m个部门中挑选包括HW在内的n个人去参加比赛,问被挑选的人中有HW的队友(同部门的人)的概率是多少。如果m个部分的人数不够组成n人的球队,输出-1. # 思路:考虑一般情况。至少有一个队友的情况较多,应该从反面考虑,即没有一个队友的情况。选完HW以后面临的状态是:事件总数为从total(m个部门的人员之和)-1个人中选n-1个的方案数,包含的事件数目为从a(a=total-s[h])中选n-1个人包含的方案数。 可以看出分母相同,可以约掉。 # 然后对于边界情况,首先判断total是否比n小。然后,如果a<n-1,表示除去HW所在的h部分之外的人不可能组成n-1个人,也就是一定要选择HW的队友,概率为1.

codeforces 312 B. Archer

·2 mins
http://codeforces.com/problemset/problem/312/B # 题意:两个人比赛射箭,先射的人射中的概率是a/b,后射的人射中的概率是c/d,问先射的人赢的概率。 思路:应该叫条件概率。。。? 不过我们可以用古典概型的思维想。每射一次看成一个点,射中的点用白色表示,没有射中的用黑色表示。如果两个人第i次都没有射中,那么就要继续第i+1 轮,而第i+1轮和之前的每一轮是独立的。等于重复这个过程。所以古典概型的样本总量应该减去宝石两个人都没有射中的点的个数,为bd-(b-a)(d-c),整理为bc+ad-a*c,设为n.要想第一个人赢,那么对于某一次,只要不是第一个人没射中,第二个人射中这种情况,就都是第一个人赢。而第一个人没射中的事件数为b-a,第二个人射中的事件数为c,总数为(b-a)*c,所以答案为(n-(b-a)*c)/n

codeforces 453 A. Little Pony and Expected Maximum

·1 min
http://codeforces.com/problemset/problem/453/A 题意:m面筛子,每面点数出现的概率相同,连续投掷n次,问出现的最大值的数学期望。 思路:手写样例。。。发现答案为 。。。记得把(1/m)^n放进去。