第三场组队赛总结(2012.08.04)

Source:Ural SU Team.GOV Contest. Petrozavodsk Summer Session, August 2011

Online Judge:Ural 1851~1861

  已经三场组队赛了,然后就是两天的休息调整~当然,还有总结!

  今天做的题是区域赛难度的一套题,正如上面source所说的。今天我们队过了2题,成绩相当平凡,过的两题分别是1854题和1860题。在比赛过程中,我只起到一个助攻的作用...........

  今天比赛前的运气不太好,在去院楼前突然觉得肚子痛了....囧,于是我就先解决拉肚子的问题再出发,所以....我又迟到了 - -    拉完肚子,状态不好也可以理解......去到机房,放下书包,队友就让我看看1860,一道递推公式的题。一开始队友解释题意错了,把计算质因数个数不假思索的看成直接求第n项。于是我就看了看题目数据,n<10^6,第一反应就是,水题??!怎么貌似没人做呢??我就跟队友讨论了一下,说道是否可以直接暴力得出结果。不过我喵了一下题目,马上发现队友坑我了....- -   原来这个是要求第n项的约数个数啊!然后我就顿时石化了......囧。于是我就想着,先放放吧.....

  刚坐下不久就有人打算出1854,不过结果是wa。于是我想,有人敢动这题,就是说题目应该不会太难。所以,我就马上看这题了。记得昨天辛辛苦苦用Pollard_Rho做出了快速分解质因数的题,我一看懂题马上就想到这个算法了,结果今天用这个算法的时候又卡了.....- -    一个随机算法,我们为了排除随机的影响,不断的修改算法的参数,连续交了不下20次...结果都是返回tle或者wa,郁闷了足足两个钟。于是,我们又放一下这题,跑去尝试1861....刚开始;还以为1861是水题,于是就试着用暴力的方法贪心了个答案出来。当然,对于一道dp题,贪心不总是能取得最优解。当时我们就意识到这样的问题了,可是怎么找都找不到反例,也想不到怎么dp。这时,一个队友想到了1854的一个方法,他也跟我解释了他的想法,然后我也认同他的想法,就根据他的思路打了个代码。那个代码,本地测试小数据没有问题,所以我们就毫不犹豫的提交上去,AC了~

  这时,有一个队伍过了递推公式的1860,所以我们也转向到投入到这题的解决上。我提供了一个方法,就是根据约数的求法,对数进行分解因子,然后把因子归类,统计得到因子数目。当时我们有想过,这可能是要用到欧拉等公式的数论题,不过我依然坚持着我的方法,不过就卡在如何统计因子个数这上面。不过我队友相当强大啊,瞬间就找到因子个数的规律了,可是要进行累加,应该会超时。然而,他很快又想到下一步,可以更快统计个数,不过思路还差一点。我听了他的想法后,嘿嘿~我的助攻出现了,告诉了他一个类似筛选素数的统计方法,然后很快就验证了可行性了。最后,我打出了代码,但是提交的时候出现了RE,不过也没事,我很快就排除了问题,是我设置错了一个变量,long long写成int了...- -!!提交上去就完美通过了~

  其他题,很多看不懂,这是一个很严重的问题!还得继续加油啊!

  组队,集思广益,几个人合作,说不定一道需要若干步骤的题就可以逐步排除疑问,最后得到满意的结果。1854,做这题的过程就很好说明了这个问题了!假设我们仍在个人赛的阶段,或许我们两个都不能做出这题了。另外一个,作为队友的队友,是一定要耐性听取队友的意见的。老实说,今天还真的差点就没认真听队友的想法,还差点就少出一题了 - -  以后要注意点,不然做少了题就不抵的!

  刚开始组队,我就毛遂自荐,当了我们The_Judge的队长,我相信我一定能在和队友一同配合合作的前提下,带领团队走向胜利的~现在当务之急仍是要懂更多算法,提升自己综合能力!

  下面是今天过的两道题的代码:

http://acm.timus.ru/problem.aspx?space=1&num=1854

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <algorithm>
  6 
  7 #define debug 0
  8 
  9 using namespace std;
 10 
 11 typedef __int64 ll;
 12 
 13 ll gcd(ll a, ll b){
 14     if (!b) return a;
 15     return gcd(b, a % b);
 16 }
 17 
 18 ll multi(ll a, ll b, ll n){
 19     ll tmp = 0;
 20 
 21     while (b){
 22         if (b & 1){
 23             tmp += a;
 24             tmp %= n;
 25         }
 26         a <<= 1;
 27         a %= n;
 28         b >>= 1;
 29     }
 30 
 31     return tmp;
 32 }
 33 
 34 ll power(ll a, ll m, ll n){
 35     ll tmp = 1;
 36 
 37     a %= n;
 38     while (m){
 39         if (m & 1) tmp = multi(tmp, a, n);
 40         a = multi(a, a, n);
 41         m >>= 1;
 42     }
 43 
 44     return tmp;
 45 }
 46 
 47 bool mr(ll n){
 48     if (n == 2) return true;
 49     if (n < 2 || ~n & 1) return false;
 50 
 51     int t = 0;
 52     ll a, x, y, u = n - 1;
 53 
 54     while (~u & 1) t++, u >>= 1;
 55     for (int i = 0; i < 8; i++){
 56         a = rand() % (n - 1) + 1;
 57         x = power(a, u, n);
 58         for (int j = 0; j < t; j++){
 59             y = multi(x, x, n);
 60             if (y == 1 && x != 1 && x != n - 1) return false;
 61             x = y;
 62         }
 63         if (x != 1) return false;
 64     }
 65 
 66     return true;
 67 }
 68 
 69 ll rho(ll n, ll c){
 70     ll x, y, d, i = 1, k = 2;
 71 
 72     x = rand() % (n - 1) + 1;
 73     y = x;
 74     while (true){
 75         i++;
 76         x = (multi(x, x, n) + c) % n;
 77         d = gcd(y - x, n);
 78         if (1 < d && d < n) return d;
 79         if (x == y) return n;
 80         if (i == k) y = x, k <<= 1;
 81     }
 82 }
 83 
 84 void fac(ll n, int k, ll *p, int &cnt){
 85     if (n == 1) return ;
 86     if (mr(n)){
 87         p[cnt++] = n;
 88         return ;
 89     }
 90 
 91     ll t = n;
 92 
 93     while (t >= n) t = rho(t, k--);
 94     fac(t, k, p, cnt);
 95     fac(n / t, k, p, cnt);
 96 }
 97 
 98 int main(){
 99     ll n;
100     int cnt;
101     ll f[80], ans;
102     bool cc;
103 
104     while (~scanf("%I64d", &n)){
105         cnt = 0;
106         fac(n, 107, f, cnt);
107         sort(f, f + cnt);
108         #if debug
109         for (int i = 0; i < cnt; i++){
110             printf("%I64d\n", f[i]);
111         }
112         #endif
113         ans = 1;
114         f[cnt] = cc = 0;
115         for (int i = 0; i < cnt; i++){
116             if (f[i] == f[i + 1]) ans *= f[i], cc = !cc;
117             else {
118                 if (cc) {
119                     ans *= f[i],
120                     cc = false;
121                 }
122             }
123         }
124         printf("%I64d\n", ans);
125     }
126 
127     return 0;
128 }

 

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <cstdlib>
 5 #include <iostream>
 6 
 7 using namespace std;
 8 typedef long long ll;
 9 
10 ll max2(ll a, ll b){
11     return a > b ? a : b;
12 }
13 
14 ll deal(ll n){
15     ll ans = 1;
16     ll t1, t2, r;
17 
18     for (ll i = 1, end = (ll)sqrt((double) n); i <= 1000005 && i < end; i++){
19         if (n % i == 0){
20             t1 = i * i;
21             t2 = n / i;
22             r = (ll) sqrt((double) i);
23             if (r * r == i){
24                 ans = max2(ans, i);
25             }
26             if (n % t1 == 0){
27                 ans = max2(ans, t1);
28             }
29             r = (ll) sqrt((double) t2);
30             if (r * r == t2){
31                 ans = t2;
32                 break;
33             }
34         }
35     }
36     return ans;
37 }
38 
39 
40 int main(){
41     ll n;
42 
43     cin >> n;
44     cout << deal(n) << endl;
45 
46     return 0;
47 }

 

两种代码的运行结果: 

http://acm.timus.ru/problem.aspx?space=1&num=1860

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <cstdlib>
 5 #include <iostream>
 6 
 7 using namespace std;
 8 typedef __int64 ll;
 9 
10 #define debug 0
11 
12 const int maxn = 1000005;
13 const ll md = 1000000007;
14 
15 ll fb[maxn + 10], pr[100000], pn, cntpr[100000], prcnt;
16 bool np[maxn + 10];
17 
18 void gf(){
19     fb[0] = fb[1] = 1;
20     for (int i = 2; i < maxn; i++){
21         fb[i] = fb[i - 1] + fb[i - 2];
22         fb[i] %= md;
23     }
24     #if debug
25     for (int i = 0; i < 10; i++){
26         printf("%lld ", fb[i]);
27     }
28     puts("");
29     #endif
30 }
31 
32 void gp(){
33     memset(np, 0, sizeof(np));
34 
35     pn = 0;
36     np[0] = np[1] = true;
37     for (ll i = 2; i < maxn; i++){
38         if (!np[i]){
39             pr[pn++] = i;
40         }
41         for (ll j = 0; j < pn && pr[j] * i < maxn; j++){
42             np[pr[j] * i] = true;
43             if (i % pr[j] == 0) break;
44         }
45     }
46     #if debug
47     printf("pn  %lld\n", pn);
48     for (int i = 0;  i < 10; i++){
49         printf("%lld ", pr[i]);
50     }
51     puts("");
52     #endif
53 }
54 
55 ll deal(ll n){
56     ll ep, i;
57 
58     memset(cntpr, 0, sizeof(cntpr));
59     for (i = 0; i < pn && pr[i] <= n; i++){
60         #if debug
61         printf("%d %lld\n", i, pr[i]);
62         #endif
63         ep = pr[i];
64         while (ep <= n){
65             for (ll j = ep; j <= n; j += ep){
66                 cntpr[i] += fb[n - j];
67                 cntpr[i] %= md;
68             }
69             ep *= pr[i];
70         }
71     }
72     #if debug
73     puts("pass");
74     #endif
75     prcnt = i;
76 
77     ll ans = 1;
78 
79     for (i = 0; i < prcnt; i++){
80         ans *= cntpr[i] + 1;
81         ans %= md;
82     }
83 
84     return ans;
85 }
86 
87 int main(){
88     int n;
89 
90     gp();
91     gf();
92     while (cin >> n)
93         cout << deal(n) << endl;
94 
95     return 0;
96 }

 

——written by Lyon

转载于:https://www.cnblogs.com/LyonLys/archive/2012/08/04/2012_08_04_Lyon.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值