码迷,mamicode.com
首页 > 其他好文 > 详细

10.4 广州集训 Day3

时间:2017-10-09 17:46:35      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:struct   排名   bsp   试题   http   之间   二叉树   treap   amp   

bst

【问题描述】
   二叉查找树是一种特殊的二叉树(每个节点最多只有两个儿子的树)。树的每个节点上存有一个唯一的值,并且满足:这个节点的左子树内所有点的值都比这个节点的值小,且右子树内所有点的值都比这个节点的值要大。
   对于一棵二叉查找树T,我们可以将一个值为x的新点插入T中,且保持树的性质。
   算法如下:

技术分享

 

   需要将x插入树T时,执行insert(x, T.root) 。
   现在有N个数需要插入一棵空树中。给定插入序列,请在每个元素被插入之后,输出所有节点的深度总和(根的深度为0)。

【输入格式】
  输入的第一行一个整数 n,表示序列长度。
  以下 n 行是序列中的数字,这些数字是各不相同的,在[1, n]区间。
【输出格式】
  输出 n 行,第 i 行整数表示第 i 个数插入树后,至这个节点的节点深度总和。
【样例输入】
8
3
5
1
6
8
7
2
4
【样例输出】
0
1
2
4
7
11
13
15
【数据规模与约定】
  对于 50%的数据, 满足N ≤ 1000
  对于100%的数据,满足N ≤ 3 ? 10^5 。

 

Solution:

  双向链表+DP。(也可以说是个模拟)

  和字面意思上一样是一个treap。

  我们考虑:当x=a[i]被插入的时候,假设T(二叉搜索树)中比x小的最大元素是p,比x大的最小元素是q。显然,p,q一定相连(可以证明)。

  (证明:p,q之间不存在其他元素,谁在父亲取决于谁先插入。)

  我们设f[i]表示x插入的深度,可得f[i]=Max(f[p],f[q])+1。

  即转化为求p,q。

  怎么求呢?

  可以用双向链表存1~n,每次删除一个元素,删除时的前驱和后继就是p,q。

  这个问题就解决了。(其实也就是模拟一下treap)

 

Other:

  现场还有大佬对着排序数组按时间戳建笛卡尔树A了此题,大概不会打...

 1 #include <iostream>
 2 
 3 #define MAXN 300005
 4 
 5 int n;
 6 int a[MAXN];
 7 int prev[MAXN], next[MAXN];
 8 int u[MAXN], v[MAXN];
 9 int deep[MAXN];
10 
11 int main(void)
12 {
13 
14     scanf("%d", & n);
15     for (int i = 1; i <= n; ++i)
16         scanf("%d", a + i);
17         
18     for (int i = 1; i <= n; ++i)
19     {
20         prev[i]  = i - 1;
21         next[i] = i + 1;
22     }
23 
24     int x;
25     for (int i = n; i > 1; --i)
26     {
27         x = a[i];
28         u[x] = prev[x];
29         v[x] = next[x];
30         next[prev[x]] = next[x];
31         prev[next[x]] = prev[x];
32     }
33 
34     long long sum = 0;
35     for (int i = 1; i <= n; ++i)
36     {
37         x = a[i];
38         
39         if ((u[x] >= 1) && (u[x] <= n))
40             if (deep[x] < deep[u[x]] + 1)
41                 deep[x] = deep[u[x]] + 1;
42         if ((v[x] >= 1) && (v[x] <= n))
43             if (deep[x] < deep[v[x]] + 1)
44                 deep[x] = deep[v[x]] + 1;
45         
46         sum += deep[a[i]];
47         
48         printf("%lld\n", sum);
49     }
50 
51     return 0;
52 }

 

ctsc:

【问题描述】
  n 人参加信息学竞赛,共有 m 道题。现在比赛已经结束,评分正在进行中,对于已经结束评测的试题,已知每名考生这道题的答案是否正确,对于未结束评测的试题,只知道每名考生是否提交答案。每个题分数固定,提交正确的答案的考生可以得到这一题的分数,分数越高排名越靠前,分数相同编号小的考生排名靠前。这 n 人中,排名最靠前的 s 人将获得入选代表队的资格,而这 s 个中将通过最终的科学委员会面试选出其中的 t 个人。输入当前的评测信息(包括是否?交,以及已经评测部分的是否正确)以及每道题的分值,问最终的 t 人代表队共有多少种组队的可能。

【输入格式】
  输入文件第一行是 m,接下去 m 行每行一个整数来表示每道题目的分值(整数是正的表示该题已经评测,否则表示该题尚未评测,该题目的分值为这个整数的绝对值)。然后是一个整数 n,接下去是一个 n 行 m 列的字母阵,字母阵只包含 YN 两种字母(Yes or No),如果第 i 题已经完成评测,那么这个字母矩阵中第 j 行第 i 列的表示第 j 名选手的第 i 题是否已经得分;如果第 i 题尚未完成评测,那么这个字母矩阵中第 j 行第 i 列的表示第 j 名选手的第 i 题是否提交了解答。接下来两个整数s,t如题意。

【输出格式】
  输出文件只有一行,即为最终的 t 人代表队的组队方案数。

【样例输入】

2
1
-10
4
NY
YN
YN
YN
3
2

【样例输出】

5

【数据规模与约定】
  对于100%的数据, 满足1 ≤N, M ≤ 50。

Solution:

Other:

  据说是最简单的组合数呢。

  考场玩了一个多小时也没证明出来。

  所以留坑...?

 

  1 #include <cstring>
  2 #include <vector>
  3 #include <string>
  4 #include <algorithm>
  5 #include <list>
  6 #include <set>
  7 #include <queue>
  8 #include <stack>
  9 #include <sstream>
 10 #include <numeric>
 11 #include <functional>
 12 #include <utility>
 13 #include <bitset>
 14 #include <iostream>
 15 #include <cmath>
 16 #include <map>
 17 
 18 using namespace std;
 19 
 20 #define MAXM 60
 21 #define MAXN 60
 22 
 23 #define DEBUG 0
 24 
 25 typedef long int  LINT;
 26 typedef long long INT64;
 27 
 28 typedef struct stProblem {
 29     int score;
 30     int state;
 31 } tProblem;
 32 tProblem problem[MAXM];
 33 
 34 typedef struct stOIer {
 35     int  id;
 36     LINT max;
 37     LINT min;
 38 } tOIer;
 39 tOIer oier[MAXN];
 40 
 41 int  p[MAXN];
 42 
 43 int  n, m, s, t;
 44 
 45 INT64 ans;
 46 
 47 INT64 calc_c(LINT m, LINT n) {
 48     if ((m < 0) || (n < 0))
 49         return 0;
 50     if (m == 0)
 51         return 1;
 52     if (n == 0)
 53         return 0;
 54     
 55     if (m > n)
 56         return 0;
 57     if (m == n)
 58         return 1;
 59     
 60     INT64 result = 1;
 61     for (int i = 0; i < n - m; ++i) {
 62         result = result * (n - i) / (1 + i);
 63     }
 64     
 65     return result;
 66 }
 67 
 68 void bubble_sort() {
 69     int bubble_sort_cmp(tOIer *a, tOIer *b);
 70     
 71     for (int i = 0; i < n - 1; ++i)
 72         for(int j = n - 1; j > i; --j)
 73             if (bubble_sort_cmp(oier + (j - 1), oier + j) < 0)
 74                 swap(oier[j - 1], oier[j]); // Defined in algorithm.h.
 75 }
 76 
 77 int bubble_sort_cmp(tOIer *a, tOIer *b) {
 78     if (a->max < b->max) {
 79         return -1;
 80     } else if (a->max == b->max) {
 81         return 0; 
 82         if (a->id > b->id)
 83             return -1;
 84         else
 85             return 1;
 86     } else { 
 87         return 1;
 88     }
 89 }
 90 
 91 int main(int argc, char *argv[]) {
 92     scanf("%d\n", & m);
 93     
 94     LINT temp_score;
 95     for (int i = 0; i < m; ++i) {
 96         scanf("%ld\n", & temp_score);
 97         if (temp_score > 0) {
 98             problem[i].score = temp_score;
 99             problem[i].state = 1;
100         } else {
101             problem[i].score = -temp_score;
102             problem[i].state = 0;
103         }
104     }
105     
106     scanf("%d\n", & n);
107     
108     char temp_state[MAXM];
109     for (int i = 0; i < n; ++i) {
110         oier[i].id = i;
111         
112         scanf("%s\n", temp_state);
113         for (int j = 0; j < m; ++j)
114             if (problem[j].state) {
115                 if (Y == temp_state[j]) {
116                     oier[i].max += problem[j].score;
117                     oier[i].min += problem[j].score;
118                 }
119             } else {
120                 if (Y == temp_state[j])
121                     oier[i].max += problem[j].score;
122             }
123     }
124     
125     scanf("%d\n", & s);
126     scanf("%d\n", & t);
127 
128     bubble_sort(); // Max Score DESC Id ASC.
129 
130     for (int i = 0; i < n; ++i)
131         for (int j = 0; j < i;
132             p[i] += ((oier[j].min > oier[i].max)
133                     || ((oier[j].min == oier[i].max) && (oier[j].id < oier[i].id))), ++j)
134             ;
135     
136     #if DEBUG
137         for (int i = 0; i < n; ++i)
138             printf("%d(ID %d) : MAX(%d), MIN(%d) P(%d)\n", i,
139                     oier[i].id, oier[i].max, oier[i].min, p[i]);
140         printf("\n");
141     #endif
142     
143     int k_min, k_max;
144     ans = 0;
145     for (int i = t - 1; i < n; ++i) {
146         if (p[i] > s - 1)
147            break;
148         
149         k_min = max(p[i] - s + t, 0);
150         k_max = min(p[i], t - 1); // t - 1 - k >= 0
151         
152         #if DEBUG
153             printf("STATE %d, MIN(%d), MAX(%d)\n", i, k_min, k_max);
154         #endif
155         
156         for (int k = k_min; k <= k_max; ++k)
157             ans += calc_c(k, p[i]) * calc_c(t - 1 - k, i - p[i]);
158     }
159     
160     printf("%lld\n", ans);
161 }

//std画风有点神奇我也不太懂...留坑等待更新自己der

 

history

  

10.4 广州集训 Day3

标签:struct   排名   bsp   试题   http   之间   二叉树   treap   amp   

原文地址:http://www.cnblogs.com/drizzly/p/7641855.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!