https://vjudge.net/contest/173780

A.假设 Pt = i,则由Ppi = i得

Ppt = t = Pi

所以就有 if Pt = i then Pi = t

 1 #include <cstdio>
 2 #include <algorithm>
 3
 4 using namespace std;
 5
 6 int n, a[110];
 7
 8 int main() {
 9     scanf("%d", &n);
10     if(n & 1) puts("-1");
11     else {
12         for(int i = 1;i <= n;i ++)
13             a[i] = i;
14         for(int i = 1;i <= n;i += 2)
15             swap(a[i], a[i + 1]);
16         for(int i = 1;i <= n;i ++)
17             printf("%d ", a[i]);
18     }
19 }

View Code

B.

C.treap练手题,STL_set练手题,链表练手题

set用的不熟所以直接上的链表

排序后时间倒序来看的思路

 1 #include <cstdio>
 2 #include <algorithm>
 3
 4 using namespace std;
 5
 6 typedef long long ll;
 7
 8 const int maxn = 50010;
 9
10 int n, b[maxn];
11
12 ll ans;
13
14 struct List{
15     int next, last;
16 }c[maxn];
17
18 struct node{
19     ll x;
20     int y;
21     bool operator < (const node &a) const {
22         return x < a.x;
23     }
24 }a[maxn];
25
26 int main() {
27     scanf("%d", &n);
28     for(int i = 1;i <= n;i ++)
29         scanf("%lld", &a[i].x), a[i].y = i;
30     ans = a[1].x;
31     a[0].x = -1000000000000ll;
32     a[n + 1].x = 1000000000000ll;
33     sort(a + 1, a + n + 1);
34     for(int i = 1;i <= n;i ++) b[a[i].y] = i;
35     for(int i = 1;i <= n;i ++) {
36         c[i].next = i + 1;
37         c[i].last = i - 1;
38     }
39     for(int i = n;i > 1;i --) {
40         ans += min(a[b[i]].x - a[c[b[i]].last].x, a[c[b[i]].next].x - a[b[i]].x);
41         c[c[b[i]].last].next = c[b[i]].next;
42         c[c[b[i]].next].last = c[b[i]].last;
43     }
44     printf("%lld\n", ans);
45     return 0;
46 }

View Code

D.边权给点,点修改和路径查询

直接上树剖+线段树,考场写狗

多组数据需要clear存边的vector,fa 和 son

修改的时候bel[i]找到第 i 条边权给的点

还要对应该点在线段树上的叶节点位置!

  1 #include <cstdio>
  2 #include <vector>
  3 #include <algorithm>
  4
  5 using namespace std;
  6
  7 const int maxn = 10010;
  8
  9 int Case, n, M;
 10
 11 struct Edge{
 12     int v, w, num;
 13 };
 14
 15 vector <Edge> edge[maxn];
 16
 17 char str[10];
 18
 19 int a, b, tr[maxn << 2];
 20
 21 int bel[maxn], siz[maxn], son[maxn], val[maxn];
 22
 23 int cnt, fa[maxn], dep[maxn], pos[maxn], dfn[maxn], top[maxn];
 24
 25 void dfs1(int u) {
 26     siz[u] = 1;
 27     for(int v, i = 0;i < edge[u].size();i ++) {
 28         v = edge[u][i].v;
 29         if(v == fa[u]) continue;
 30         fa[v] = u;
 31         dep[v] = dep[u] + 1;
 32         val[v] = edge[u][i].w;
 33         bel[edge[u][i].num] = v;
 34         dfs1(v), siz[u] += siz[v];
 35         if(siz[son[u]] < siz[v]) son[u] = v;
 36     }
 37 }
 38
 39 void dfs2(int u, int tp) {
 40     top[u] = tp, pos[u] = ++ cnt, dfn[cnt] = u;
 41     if(son[u]) dfs2(son[u], tp);
 42     for(int v, i = 0;i < edge[u].size();i ++)  {
 43         v = edge[u][i].v;
 44         if(v != fa[u] && v != son[u])
 45             dfs2(v, v);
 46     }
 47 }
 48
 49 void change(int i, int x) {
 50     i = pos[i];
 51     for(tr[i += M] = x, i >>= 1;i;i >>= 1)
 52         tr[i] = max(tr[i << 1], tr[i << 1 | 1]);
 53 }
 54
 55 int mmax(int s, int t) {
 56     int res = -666666666;
 57     for(s += M - 1, t += M + 1;s ^ t ^ 1;s >>= 1, t >>= 1) {
 58         if(~ s & 1) res = max(res, tr[s ^ 1]);
 59         if(  t & 1) res = max(res, tr[t ^ 1]);
 60     }
 61     return res;
 62 }
 63
 64 void query(int u, int v) {
 65     int fu = top[u], fv = top[v], res = -666666666;
 66     while(fu != fv) {
 67         if(dep[fu] < dep[fv]) swap(u, v), swap(fu, fv);
 68         res = max(res, mmax(pos[fu], pos[u]));
 69         u = fa[fu], fu = top[u];
 70      }
 71      if(u == v) printf("%d\n", res);
 72      else {
 73          if(dep[u] < dep[v]) swap(u, v);
 74          printf("%d\n", max(res, mmax(pos[v] + 1, pos[u])));
 75      }
 76 }
 77
 78 int main() {
 79 //freopen("test.txt","r",stdin);
 80     val[1] = -666666666;
 81     int u, v, w;
 82     scanf("%d", &Case);
 83     while(Case --) {
 84         cnt = 0;
 85         scanf("%d", &n);
 86         for(int i = 1;i <= n;i ++) edge[i].clear(), fa[i] = son[i] = 0;
 87         for(int i = 1;i < n;i ++) {
 88             scanf("%d %d %d", &u, &v, &w);
 89             edge[u].push_back((Edge){v, w, i});
 90             edge[v].push_back((Edge){u, w, i});
 91         }
 92         dfs1(1), dfs2(1, 1);
 93         for(M = 1;M < n + 2; M <<= 1);
 94         for(int i = 1;i <= n;i ++) tr[i + M] = val[dfn[i]];
 95         for(int i = n + 1;i <= M + 1;i ++) tr[i + M] = val[1];
 96         for(int i = M;i;i --) tr[i] = max(tr[i << 1], tr[i << 1 | 1]);
 97         while(scanf("%s", str), str[0] != 'D') {
 98             if(str[0] == 'C') scanf("%d %d", &a, &b), change(bel[a], b);
 99             else scanf("%d %d", &a, &b), query(a, b);
100         }
101         puts("");
102     }
103 }

View Code

E.考场上脑补出来一个正解,可惜只差了一步

两个单调队列,一增一减,从前向后扫

当扫到某个位置,最大差距 > R 时

踢出两个队列中位置最靠前的元素直至差距 <= R

如果这是最大差距 >= L 则更新答案即可

时间复杂度O(n),别人说这是个做过的RMQ啊...

 1 #include <cstdio>
 2 #include <algorithm>
 3
 4 using namespace std;
 5
 6 const int maxn = 100010;
 7
 8 int n, x, y, m, a[maxn], q1[maxn], q2[maxn];
 9
10 int l1, r1, l2, r2, t;
11
12 int main() {
13     while(scanf("%d %d %d", &n, &x, &y) != EOF) {
14         for(int i = 1;i <= n;i ++)
15             scanf("%d", &a[i]);
16         m = t = 0, l1 = l2 = 1, r1 = r2 = 0;
17         for(int i = 1;i <= n;i ++) {
18             while(l1 <= r1 && a[i] > a[q1[r1]]) r1 --;
19             q1[++ r1] = i;
20             while(l2 <= r2 && a[i] < a[q2[r2]]) r2 --;
21             q2[++ r2] = i;
22             while(l1 <= r1 && l2 <= r2 && a[q1[l1]] > a[q2[l2]] + y) {
23                 if(q1[l1] < q2[l2]) t = q1[l1 ++];
24                 else t = q2[l2 ++];
25             }
26             if(l1 <= r1 && l2 <= r2 && a[q1[l1]] >= a[q2[l2]] + x) m = max(m, i - t);
27         }
28         printf("%d\n", m);
29     }
30     return 0;
31 }

View Code

F.就是枚举min,然后单调队列求出左右拓展多远就好了

 1 #include <cstdio>
 2
 3 const int maxn = 100010;
 4
 5 int l = 1, r, q[maxn];
 6
 7 int L, R, n, a[maxn], b[maxn], c[maxn];
 8
 9 long long ans = -1, tmp, s[maxn];
10
11 int main() {
12     scanf("%d", &n);
13     for(int i = 1;i <= n;i ++)
14         scanf("%d", &a[i]), s[i] = a[i] + s[i - 1];
15     for(int i = 1;i <= n;i ++) {
16         while(l <= r && a[i] < a[q[r]]) b[q[r]] = i - q[r], r --;
17         q[++ r] = i;
18     }
19     while(l <= r) b[q[r]] = n + 1 - q[r], r --;
20     l = 1, r = 0;
21     for(int i = n;i;i --) {
22         while(l <= r && a[i] < a[q[r]]) c[q[r]] = q[r] - i, r --;
23         q[++ r] = i;
24     }
25     while(l <= r) c[q[r]] = q[r], r --;
26     for(int i = 1;i <= n;i ++) {
27         tmp = (s[i + b[i] - 1] - s[i - c[i]]) * a[i];
28         if(tmp > ans) ans = tmp, L = i - c[i] + 1, R = i + b[i] - 1;
29     }
30     printf("%lld\n%d %d", ans, L ,R);
31     return 0;
32 }

View Code

G.开始没看清题发现大家都会写区间众数?

连续的相同...线段树傻逼题

 1 #include <cstdio>
 2 #include <algorithm>
 3
 4 using namespace std;
 5
 6 const int maxn = 100010;
 7
 8 struct node{
 9     int ls, rs, lc, rc, mm;
10 }tr[maxn << 2];
11
12 int n, m, c[maxn];
13
14 node operator +(const node &a, const node &b) {
15     node res;
16     res.ls = a.ls;
17     res.lc = a.lc;
18     res.rs = b.rs;
19     res.rc = b.rc;
20     res.mm = max(a.mm, b.mm);
21     if(a.rc == b.lc) {
22         res.mm = max(res.mm, a.rs + b.ls);
23         if(a.lc == a.rc) res.ls += b.ls;
24         if(b.lc == b.rc) res.rs += a.rs;
25     }
26     return res;
27 }
28
29 void build(int o, int l, int r) {
30     if(l == r) {
31         tr[o] = (node){1, 1, c[r], c[r], 1};
32         return;
33     }
34     int mid = (l + r) >> 1;
35     build(o << 1, l, mid);
36     build(o << 1 | 1, mid + 1, r);
37     tr[o] = tr[o << 1] + tr[o << 1 | 1];
38 }
39
40 node ask(int o, int l, int r, int s, int t){
41     if(s <= l && r <= t) return tr[o];
42     int mid = (l + r) >> 1;
43     if(t <= mid) return ask(o << 1, l, mid, s, t);
44     else if(s > mid) return ask(o << 1 | 1, mid + 1, r, s, t);
45     else return ask(o << 1, l, mid, s, t) + ask(o << 1 | 1, mid + 1, r, s, t);
46 }
47
48 int main() {
49     int a, b;
50     while(scanf("%d %d", &n, &m), n != 0) {
51         for(int i = 1;i <= n;i ++)
52             scanf("%d", &c[i]);
53         build(1, 1, n);
54         //printf("%d %d %d\n",tr[1].mm,tr[6].rc, tr[7].lc);
55         while(m --) {
56             scanf("%d %d", &a, &b);
57             printf("%d\n", ask(1, 1, n, a, b).mm);
58         }
59     }
60 }

View Code

H.

I.无修改查询树上路径和,随便做啦

dis[u] + dis[v] - dis[lca] * 2

我直接上的bfs树剖求lca

 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4
 5 using namespace std;
 6
 7 const int maxn = 40010;
 8
 9 struct Edge{
10     int v, w;
11 };
12
13 vector <Edge> edge[maxn];
14
15 int Case, n, m, a, b, c, dis[maxn];
16
17 int l, r, q[maxn], siz[maxn], son[maxn];
18
19 int cnt, fa[maxn], dep[maxn], top[maxn];
20
21 int lca(int u, int v) {
22     int fu = top[u], fv = top[v];
23     while(fu != fv) {
24         if(dep[fu] < dep[fv]) swap(u, v), swap(fu, fv);
25         u = fa[fu], fu = top[u];
26      }
27      return dep[u] < dep[v] ? u : v;
28 }
29
30 int main() {
31     int u, v, w;
32     scanf("%d", &Case);
33     while(Case --) {
34         scanf("%d %d", &n, &m);
35         for(int i = 1;i < n;i ++) {
36             scanf("%d %d %d", &u, &v, &w);
37             edge[u].push_back((Edge){v, w});
38             edge[v].push_back((Edge){u, w});
39         }
40         l = r = 0, q[++ r] = 1;
41         while(l <= r) {
42             u = q[l ++];
43             siz[u] = 1, son[u] = top[u] = 0;
44             for(int i = 0;i < edge[u].size();i ++) {
45                 v = edge[u][i].v;
46                 if(v == fa[u]) continue;
47                 fa[v] = u, q[++ r] = v, dep[v] = dep[u] + 1, dis[v] = dis[u] + edge[u][i].w;
48             }
49         }
50         for(int i = n;i > 1;i --) {
51             siz[fa[q[i]]] += siz[q[i]];
52             if(!son[fa[q[i]]] || siz[son[fa[q[i]]]] < siz[q[i]]) son[fa[q[i]]] = q[i];
53         }
54         for(int i = 1;i <= n;i ++) {
55             u = q[i];
56             if(son[fa[u]] == u) top[u] = top[fa[u]];
57             else top[u] = u;
58         }
59         while(m --) {
60             scanf("%d %d", &a, &b);
61             c = lca(a, b);
62             printf("%d\n", dis[a] - dis[c] - dis[c] + dis[b]);
63         }
64     }
65 }

View Code

J.裸树状数组

 1 #include <cstdio>
 2
 3 const int maxn = 50010;
 4
 5 int c[maxn], a[maxn];
 6
 7 int Case, n, x, y;
 8
 9 char str[10];
10
11 int lowbit(int x) {
12     return (x & (-x));
13 }
14
15 int ask(int i) {
16     int res = 0;
17     while(i > 0) res += c[i], i -= lowbit(i);
18     return res;
19 }
20
21 void add(int i, int x) {
22     while(i <= n) c[i] += x, i += lowbit(i);
23 }
24
25
26 int main() {
27     //freopen("test.txt", "r", stdin);
28     scanf("%d", &Case);
29     for(int tt = 1;tt <= Case;tt ++) {
30         printf("Case %d:\n", tt);
31         scanf("%d", &n);
32         for(int i = 1;i <= n;i ++)
33             scanf("%d", &a[i]), a[i] += a[i - 1];
34         while(scanf("%s", str), str[0] != 'E') {
35             scanf("%d %d", &x, &y);
36             if(str[0] == 'Q') printf("%d\n", ask(y) - ask(x - 1) + a[y] - a[x - 1]);
37             else add(x, y * (str[0] == 'A' ? 1 : -1));
38         }
39         for(int i = 1;i <= n;i ++) c[i] = 0;
40     }
41     return 0;
42 }

View Code

K.区间加和区间求和,差分树状数组除非有封装好的板子

不然现场还是只能写线段树

 1 #include <cstdio>
 2 #include <algorithm>
 3
 4 using namespace std;
 5
 6 typedef long long ll;
 7
 8 const int maxn = 100010;
 9
10 int n, m, d[maxn];
11
12 char str[10];
13
14 int a, b, c;
15
16 ll s[maxn];
17
18 struct node{
19     ll lazy, sum;
20 }tr[maxn << 2];
21
22 void pushup(int o) {
23     tr[o].sum = tr[o << 1].sum + tr[o << 1 | 1].sum;
24 }
25
26 void pushdown(int o, int l, int r) {
27     if(!tr[o].lazy) return;
28     int mid = (l + r) >> 1;
29     tr[o << 1].sum += tr[o].lazy * (mid - l + 1);
30     tr[o << 1 | 1].sum += tr[o].lazy * (r - mid);
31     tr[o << 1].lazy += tr[o].lazy;
32     tr[o << 1 |1].lazy += tr[o].lazy;
33     tr[o].lazy = 0;
34 }
35
36 void add(int o, int l, int r, int s, int t, int x) {
37     if(l != r) pushdown(o, l, r);
38     if(s <= l && r <= t) {
39         tr[o].lazy += x;
40         tr[o].sum += 1ll * x * (r - l + 1);
41         return;
42     }
43     int mid = (l + r) >> 1;
44     if(s <= mid) add(o << 1, l, mid, s, t, x);
45     if(mid < t) add(o << 1 | 1, mid + 1, r, s, t, x);
46     pushup(o);
47 }
48
49 ll query(int o, int l, int r, int s, int t) {
50     if(l != r) pushdown(o, l, r);
51     if(s <= l && r <= t) return tr[o].sum;
52     ll res = 0;
53     int mid = (l + r) >> 1;
54     if(s <= mid) res += query(o << 1, l, mid, s, t);
55     if(mid < t) res += query(o << 1 | 1, mid + 1, r, s, t);
56     pushup(o);
57     return res;
58 }
59
60 int main(int argc, char const *argv[]){
61     scanf("%d %d", &n, &m);
62     for(int i = 1;i <= n;i ++)
63         scanf("%d", &d[i]), s[i] = s[i - 1] + d[i];
64     while(m --) {
65         scanf("%s %d %d", str, &a, &b);
66         if(str[0] == 'Q') printf("%lld\n", query(1, 1, n, a, b) + s[b] - s[a - 1]);
67         else scanf("%d", &c), add(1, 1, n, a, b, c);
68     }
69     return 0;
70 }

View Code

L.vector会TLE改邻接表能过...***

dfs序 + 树状数组

 1 #include <cstdio>
 2
 3 const int maxn = 200010;
 4
 5 int n, m, q, a[maxn], c[maxn], st[maxn], en[maxn];
 6
 7 int tot, head[maxn], to[maxn], next[maxn];
 8
 9 void ade(int x, int y) {
10     to[++ tot] = y, next[tot] = head[x], head[x] = tot;
11 }
12
13 int lowbit(int x) {
14     return (x & (-x));
15 }
16
17 int ask(int i) {
18     int res = 0;
19     while(i > 0) res += c[i], i -= lowbit(i);
20     return res;
21 }
22
23 void add(int i, int x) {
24     while(i <= n) c[i] += x, i += lowbit(i);
25 }
26
27 void dfs(int x, int f) {
28     a[x] = 1, st[x] = ++ m;
29     for(int y, i = head[x];i;i = next[i]) {
30         y = to[i];
31         if(y == f) continue;
32         dfs(y, x);
33     }
34     en[x] = m;
35 }
36
37 char str[10];
38
39 int x;
40
41 int main() {
42     scanf("%d", &n);
43     for(int u, v, i = 1;i < n;i ++) {
44         scanf("%d %d", &u, &v);
45         ade(u, v), ade(v, u);
46     }
47     dfs(1, 1);
48     scanf("%d", &q);
49     while(q --) {
50         scanf("%s %d", str, &x);
51         if(str[0] == 'Q') printf("%d\n", ask(en[x]) - ask(st[x] - 1) + en[x] - st[x] + 1);
52         else {
53             if(a[x]) add(st[x], -1), a[x] = 0;
54             else add(st[x], 1), a[x] = 1;
55         }
56     }
57     return 0;
58 }

View Code

转载于:https://www.cnblogs.com/ytytzzz/p/7253869.html

bupt summer training for 16 #5 ——数据结构相关推荐

  1. bupt summer training for 16 #2 ——计算几何

    https://vjudge.net/contest/171368#overview A.一个签到题,用叉积来判断一个点在一条线的哪个方向 可以二分,数据范围允许暴力 1 #include <c ...

  2. bupt summer training for 16 #8 ——字符串处理

    https://vjudge.net/contest/175596#overview A.设第i次出现的位置左右端点分别为Li,Ri 初始化L0 = 0,则有ans = sum{ (L[i] - L[ ...

  3. bupt summer training for 16 #3 ——构造

    https://vjudge.net/contest/172464 后来补题发现这场做的可真他妈傻逼 A.签到傻逼题,自己分情况 1 #include <cstdio> 2 #includ ...

  4. 2020 BUPT Winter Training #1 Div.1

    2020 BUPT Winter Training #1 Div.1 这些题真的很不错 读完题一道都不会 补完每一道都骂自己sb 文章目录 [A - Cover it!](https://vjudge ...

  5. 数据结构c语言版第16页,数据结构c语言版

    数据结构c语言版[编辑] 概述 <数据结构C语言版>本书的前半部分从抽象数据类型的角度讨论各种基本类型的数据结构及其应用;后半部分主要讨论查找和排序的各种实现方法及综合分析比较 出版信息 ...

  6. 2018 BUPT Winter Training #3 Div.2

    A - The order of a Tree 根据二叉搜索树的性质,我们知道key[Lchild[r]]≤key[r]≤key[Rchild[r]]key[Lchild[r]]\le key[r]\ ...

  7. Transformer: Training and fine-tuning(六)

    Transformer: Training and fine-tuning(六) 语译分西 2020-12-09 19:43:43  73  收藏 1 分类专栏: 文本挖掘,情感分类 文章目录 1.F ...

  8. 获取用户列表为空_数据结构和算法(Golang实现)(15)常见数据结构-列表

    列表 一.列表 List 我们又经常听到 列表 List 数据结构,其实这只是更宏观的统称,表示存放数据的队列. 列表 List:存放数据,数据按顺序排列,可以依次入队和出队,有序号关系,可以取出某序 ...

  9. 《数据结构与算法之美》学习汇总

    此篇文章是对自己学习这门课程的一个总结和课后的一些练习,做一个汇总,希望对大家有帮助.本人是半路程序员,2018年2月开始学习C++的,下面的代码基本都是C++11版本的,代码有错误的地方请不吝留言赐 ...

最新文章

  1. Android环境下通过C框架层控制WIFI【转】
  2. java代码详细注释_java代码详细注释
  3. Gradle Build速度加快终极方法(android studio)
  4. Missing URI template variable 'XXXX' for method parameter of type String
  5. mysql leave的作用_MySQL数据库中DELIMITER的作用
  6. Spring-Bean配置-使用外部属性文件(转)
  7. 概率图模型(05): 揭示局部概率模型, 稀疏化网络表示(Structured-CPDs)
  8. XSS学习之xss20
  9. 51单片机八段数码c语言程序,51单片机做的音乐盒,带八段数码管显示程序+Proteus仿真...
  10. 如何优化Urchin配置文件每月数据库的磁盘存储空间
  11. 平衡运输问题及其表上作业法---指派问题及其匈牙利解法
  12. XML Guest Book
  13. 黑盒测试、灰盒测试、白盒测试、单元测试是什么?它们有什么区别?
  14. 区域卫生平台用户分析
  15. 浅谈电子配线架智能布线管理系统(二)
  16. 2014迅雷校园招聘(C++)(笔试题(四)
  17. 2021一款精美图片压缩网站源码
  18. python编译make_编译安装python3时make install出错
  19. PHP闭包函数与闭包函数回调
  20. python迭代器、生成器及装饰器

热门文章

  1. 如何实现接口的幂等性?
  2. js不区分大小写查找字符串
  3. Outh2协议有哪四种授权模式?
  4. Java 并发编程AQS--源码解读
  5. Spring 事务使用详解
  6. 什么是 gRPC ?
  7. IDEA 在头注解上添加用户名称和时间
  8. 关于CSS中定位的个人理解
  9. Web 的MSN,可以不用装客户端
  10. javscript插件汇总