CF #174 div2 练习

2014-10-31 20:15:23

总结:这场有点怪怪的吧,a比b难,c不难,然后d题虽然知道怎么写,但就是tle - =!

A:求素数的原根个数,根据定理:如果正整数p是素数,那么其原根个数是phi(p-1),所以直接求一遍欧拉函数即可。12min(中速)

  (当然有人根据定义直接暴力检索也可以)

 1 /*************************************************************************
 2     > File Name: a.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Fri 31 Oct 2014 06:10:04 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int p;
28 
29 int main(){
30     scanf("%d",&p);
31     --p;
32     int ans = p;
33     int top = sqrt(1.0 * p);
34     for(int i = 2; i <= top; ++i) if(p % i == 0){
35         while(p % i == 0) p /= i;
36         ans = ans * (i - 1) / i;
37     }
38     if(p != 1) ans = ans * (p - 1) / p;
39     printf("%d\n",ans);
40     return 0;
41 }
View Code

B:感觉这题放a比较合理,英语阅读理解。19min(中快速)

 1 /*************************************************************************
 2     > File Name: b.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Fri 31 Oct 2014 06:27:18 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int n;
28 char s[200010];
29 
30 int main(){
31     scanf("%d",&n);
32     scanf("%s",s);
33     int len = strlen(s);
34     int ci = 0,ca = 0;
35     for(int i = 0; i < len; ++i){
36         if(s[i] == 'A') ca++;
37         else if(s[i] == 'I') ci++;
38     }
39     if(ci > 1) printf("0\n");
40     else if(ci == 1) printf("1\n");
41     else printf("%d\n",ca);
42     return 0;
43 }
View Code

C:技巧题,相当于处理区间更新(或许可以用XX树来写吧),我的做法:开了一个pair数组,first记录更新的区间左端,second记录区间右端,如果只是加点的话,那么新加的点的first和second都置为他自己的数值(相当于区间就一个点),最后,处理删点的时候要处理一下区间是否结束即可。53min(中速)

  (因为没开long long,wa了三发。竟然3发了才发现,真是太弱了!)

 1 /*************************************************************************
 2     > File Name: c.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Fri 31 Oct 2014 06:42:26 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int n;
28 pair<ll,ll> tag[200010];
29 int t,a,k,x,sz;
30 ll sum;
31 
32 int main(){
33     memset(tag,0,sizeof(tag));
34     sz = 1;
35     sum = 0;
36     scanf("%d",&n);
37     while(n--){
38         scanf("%d",&t);
39         if(t == 1){
40             scanf("%d%d",&a,&x);
41             tag[1].first += x;
42             tag[a].second += x;
43             sum += a * x;
44         }
45         else if(t == 2){
46             scanf("%d",&k);
47             ++sz;
48             tag[sz].first += k;
49             tag[sz].second += k;
50             sum += k;
51         }
52         else if(sz >= 2){
53             sum -= tag[sz].second;
54             tag[sz].second -= tag[sz].first;
55             tag[sz - 1].second += tag[sz].second;
56             tag[sz].first = tag[sz].second = 0;
57             --sz;
58         }
59         printf("%.10f\n",1.0 * sum / sz);
60     }
61     return 0;
62 }

D:记忆化搜索题,赛后才A的。。。

 1 /*************************************************************************
 2     > File Name: d.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Fri 31 Oct 2014 08:45:25 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int n;
28 ll a[200010];
29 ll dp[200010][2];
30 bool vis[200010][2];
31 
32 ll Dfs(int x,bool flag){
33     if(x <= 0 || x > n)
34         return 0;
35     if(vis[x][flag]){
36         if(dp[x][flag] > 0) return dp[x][flag];
37         return -1;
38     }
39     vis[x][flag] = 1;
40     ll tmp;
41     if(flag) tmp = Dfs(x + a[x],flag ^ 1);
42     else tmp = Dfs(x - a[x],flag ^ 1);
43     if(tmp == -1) dp[x][flag] = -1;
44     else dp[x][flag] = tmp + a[x];
45     return dp[x][flag];
46 }
47 
48 int main(){
49     scanf("%d",&n);
50     for(int i = 2; i <= n; ++i)
51         scanf("%I64d",a + i);
52     for(int i = 1; i < n; ++i){
53         a[1] = i;
54         dp[1][1] = 0;
55         vis[1][1] = false;
56         printf("%I64d\n",Dfs(1,1));
57     }
58     return 0;
59 }

 

posted @ 2014-10-31 21:14  Naturain  阅读(149)  评论(0编辑  收藏  举报