Codeforces Round #263 (Div. 1) 题解

A:Appleman and Toastman

题意:两个人玩游戏 初始第一个人给第二个人一个数组 第二个人把数组中每个数相加的和加到他的总得分里面,然后把这个数组还给第一个人,第一个人进行操作:若数组中只剩下一个数,就把这个数组扔了,否则把这个数组拆成两个数组扔回给第二个人,求第二个人的最大得分。

题解:游戏结束即为数组中N个数全被拆成了单独的一个数,而且我们可以知道若一个数在第一个人操作第K次时候变成只有一个数的数组,那么这个数在第二个人那算了K+1次,于是不难想到贪心算法,即让越大的数算的次数越多,于是从小到大排序后,第I个数在第I次变成单独的数组,于是第I个数被算了I+1次,注意最后一次是把第N-1和N个数都变成了单独的,于是最后两个数都是被算了N次,问题得到解决。

 1 #include <cstdio>
 2
 3 #include <cmath>
 4
 5 #include <iostream>
 6
 7 #include <cstring>
 8
 9 #include <algorithm>
10
11
12
13 using namespace std;
14
15 long long a[500000],ans,x;
16
17 int n;
18
19 int main()
20
21 {
22
23     scanf("%d",&n);
24
25     if (n==1)
26
27     {
28
29         scanf("%I64d",&x);
30
31         printf("%I64d",x);
32
33         return 0;
34
35     }
36
37     for (int i=1;i<=n;++i) scanf("%I64d",&a[i]);
38
39     sort(a+1,a+n+1);
40
41     for (int i=1;i<=n;++i) ans+=(i+1)*a[i];
42
43     ans-=a[n];
44
45     printf("%I64d",ans);
46
47     return 0;
48
49 }

B:Appleman and Tree

题意:给出一棵树,每个节点有黑色或白色,现在要求删掉一些边后形成的联通块每个块内都恰好有一个黑点,求方案数。

题解:树形dp

dp[i][0]表示节点i所在的子树联通块内有0个黑点时的子树内划分方案数

dp[i][1]表示节点i所在的子树联通块内有1个黑点时的子树内划分方案数

转移:对于i的一个孩子j

考虑:dp[i][0]

若j所在子树联通块也没有黑点,则需要把他和i连起来,要不然永远也不会有黑点。

若j所在子树联通块内有黑点,则根据状态定义把i和j之间的边删除掉。

得到:dp[i][0]=dp[i][0]*dp[j][0]+dp[i][0]*dp[j][0]

考虑:dp[i][1]

若j所在子树联通块内没有黑点,则需要把他和i连起来,要不然永远也不会有黑点。

若j所在子树联通块内有黑点:

①若i所在联通块有黑点,则把i和j断开

②若i所在联通块没有黑点,则把i和j连上

得到:dp[i][1]=dp[i][1]*dp[j][0]+dp[i][1]*dp[j][1]+dp[i][0]*dp[j][1] 至此问题得到解决。

 1 #include <cstdio>
 2
 3 #include <iostream>
 4
 5 #include <cmath>
 6
 7 #include <cstring>
 8
 9 #include <algorithm>
10
11 const int mod=1e9+7;
12
13 using namespace std;
14
15 int n,a[100005],x;
16
17 long long dp[100005][5];
18
19 int main()
20
21 {
22
23     memset(dp,0,sizeof(dp));
24
25     scanf("%d",&n);
26
27     for (int i=1;i<n;++i) scanf("%d",&a[i]);
28
29     for (int i=0;i<n;++i)
30
31     {
32
33         scanf("%d",&x);
34
35         dp[i][x]=1;
36
37     }
38
39     for (int i=n-1;i>=1;--i)
40
41     {
42
43         dp[a[i]][1]=(dp[a[i]][1]*(dp[i][0]+dp[i][1])+dp[a[i]][0]*dp[i][1])%mod;
44
45         dp[a[i]][0]=(dp[a[i]][0]*(dp[i][0]+dp[i][1]))%mod;
46
47     }
48
49     printf("%I64d\n",dp[0][1]);
50
51     return 0;
52
53 }

C:Appleman and a Sheet of Paper

题解:一个折纸的过程,有两种操作,第一种是把前X单位的纸折到后半部分的上面,第二种为询问长度L到R区间实际上纸的长度为多少,即那一段纸的厚度为多少。

题意:实际上直接模拟这个过程即可。记录前缀和sum[i]表示到i为止一共有几段纸,然后就是每次模拟这个过程更新sum数组。

   对于折超过一半的处理可以等效成将令一半叠上来,记录一个是否翻转过的标记即可,因为随着折叠纸的长度不断变小,复杂度是可以接受的。

 1 #include <cstdio>
 2
 3 #include <cmath>
 4
 5 #include <iostream>
 6
 7 #include <cstring>
 8
 9 #include <algorithm>
10
11
12
13 using namespace std;
14
15 int n,m,dq,rev,last,sum[200000],z,l,r;
16
17 int main()
18
19 {
20
21     scanf("%d%d",&n,&m);
22
23     dq=n;rev=0;last=0;
24
25     for (int i=1;i<=n;++i) sum[i]=i;
26
27     for (int t=1;t<=m;++t)
28
29     {
30
31         scanf("%d",&z);
32
33         if (z==1)
34
35         {
36
37             scanf("%d",&l);
38
39             if (l>dq-l)
40
41             {
42
43                 l=dq-l;
44
45                 rev^=1;
46
47             }
48
49             if (rev)
50
51             {
52
53                 for (int i=dq-l;i<dq;++i) sum[last+2*(dq-l)-i]+=(n-sum[last+i]);
54
55             }
56
57             else
58
59             {
60
61                 last+=l;
62
63                 for (int i=0;i<l;++i) sum[last+i]-=sum[last-i];
64
65             }
66
67             dq-=l;
68
69         }
70
71         else
72
73         {
74
75             scanf("%d%d",&l,&r);
76
77             if (rev)
78
79             {
80
81                 int temp=dq-r;
82
83                 r=dq-l;
84
85                 l=temp;
86
87             }
88
89             printf("%d\n",sum[last+r]-sum[last+l]);
90
91         }
92
93         //for (int i=1;i<=n;++i) cout<<sum[i]<<endl;
94
95     }
96
97     return 0;
98
99 }

时间: 2024-09-29 09:44:10

Codeforces Round #263 (Div. 1) 题解的相关文章

Codeforces Round #262 (Div. 2) 题解

A. Vasya and Socks time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasya has n pairs of socks. In the morning of each day Vasya has to put on a pair of socks before he goes to school. When

Codeforces Round #FF (Div. 2) 题解

比赛链接:http://codeforces.com/contest/447 A. DZY Loves Hash time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output DZY has a hash table with p buckets, numbered from 0 to p?-?1. He wants to insert n 

Codeforces Round #263 (Div. 1) A B C

Codeforces Round #263 (Div. 1) A:贪心,排个序,然后从后往前扫一遍,计算后缀和,之后在从左往右扫一遍计算答案 B:树形DP,0表示没有1,1表示有1,0遇到0必然合并,0遇到1也必然合并,1遇到0必然合并,1遇到1,必然切断,按照这样去转移即可 C:树状数组,再利用启发式合并,开一个l,r记录当前被子左右下标,和一个flip表示是否翻转 代码: A: #include <cstdio> #include <cstring> #include <

Codeforces Round #259 (Div. 2) 题解

A. Little Pony and Crystal Mine time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Twilight Sparkle once got a crystal from the Crystal Mine. A crystal of size n (n is odd; n?>?1) is an n?×?n 

Codeforces Round #177 (Div. 2) 题解

[前言]咦?现在怎么流行打CF了?于是当一帮大爷在执着的打div 1的时候,我偷偷的在刷div 2.至于怎么决定场次嘛,一般我报一个数字A,随便再拉一个人选一个数字B.然后开始做第A^B场.如果觉得机密性不高,来点取模吧.然后今天做的这场少有的AK了.(其实模拟赛只做完了4题,最后1题来不及打了) 等等,话说前面几题不用写题解了?算了,让我难得风光一下啦. [A] A. Polo the Penguin and Segments time limit per test 2 seconds mem

贪心 Codeforces Round #263 (Div. 2) C. Appleman and Toastman

题目传送门 1 /* 2 贪心:每次把一个丢掉,选择最小的.累加求和,重复n-1次 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-1 13:20:01 7 File Name :A.cpp 8 *************************************************/ 9 10 #include <cstdio>

Codeforces Round #534 (Div. 2)题解

Codeforces Round #534 (Div. 2)题解 A. Splitting into digits 题目大意 将一个数字分成几部分,几部分求和既是原数,问如何分可以使得分出来的各个数之间的差值尽可能小 解题思路 将n分成n个1相加即可 AC代码 #include<cstring> #include<string> #include<iostream> #include<cstdio> using namespace std; int main

Codeforces Round #561 (Div. 2) 题解

Codeforces Round #561 (Div. 2) 题解 题目链接 A. Silent Classroom 水题. Code #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 105; int n; char s[N], t[N]; int main() { cin >> n; for(int i = 1; i <= n; i++) { scanf(&q

Codeforces Round #608 (Div. 2) 题解

目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 程序 D. Portals 题意 做法 程序 E. Common Number 题意 做法 程序 结束语 Codeforces Round #608 (Div. 2) 题解 前言 题目链接:仅仅只是为了方便以题目作为关键字能查找到我的题解而已(逃 Codeforces 1271A Codeforce