题目在这里

A.似乎是个并查集+???

B.10W的范围,似乎可以暴力来一发二分+sort?

但我猜正解可以O(nlogn)?

C.单调队列入门题目

  1. #include <cstdio>
  2.  
  3. int n, m, a[], ans1[], ans2[];
  4.  
  5. struct queue_1 {
  6. int q[];
  7. int l, r;
  8. queue_1(): l(), r() {}
  9. int front() {
  10. return q[l];
  11. }
  12. void push(int i) {
  13. while(l <= r && q[l] + m <= i) l ++;
  14. while(r >= l && a[i] <= a[q[r]]) r --;
  15. q[++ r] = i;
  16. }
  17. }q1;
  18.  
  19. struct queue_2 {
  20. int q[];
  21. int l, r;
  22. queue_2(): l(), r() {}
  23. int front() {
  24. return q[l];
  25. }
  26. void push(int i) {
  27. while(l <= r && q[l] + m <= i) l ++;
  28. while(r >= l && a[i] >= a[q[r]]) r --;
  29. q[++ r] = i;
  30. }
  31. }q2;
  32.  
  33. void getint(int &x) {
  34. x = ;
  35. static int c, f;
  36. while(c = getchar(), (c < '' || c > '') && c != '-');
  37. if(c != '-') x = c - '', f = ;
  38. else f = , x = ;
  39. while(c = getchar(), c >= ''&&c <= '') x = x * + c - '';
  40. if(f) x = -x;
  41. }
  42.  
  43. int main() {
  44. getint(n), getint(m);
  45. for(int i = ;i < m;i ++) getint(a[i]), q1.push(i), q2.push(i);
  46. for(int i = m;i <= n;i ++)
  47. getint(a[i]), q1.push(i), q2.push(i),
  48. ans1[++ ans1[]] = a[q1.front()], ans2[++ ans2[]] = a[q2.front()];
  49. for(int i = ;i <= ans1[];i ++) printf("%d ", ans1[i]);puts("");
  50. for(int i = ;i <= ans2[];i ++) printf("%d ", ans2[i]);
  51. return ;
  52. }

我怎么就脑子抽了写了个极丑的封装呢

注意选择C++,G++会超时

D.简单的单点修改+区间查询max

线段树即可,据说这题还能有树状数组的骚操作?

比较懒,写了两个好写一点的

分块

  1. #include <cstdio>
  2.  
  3. int n, m, siz;
  4. int a[], mmax[];
  5.  
  6. int max(int x, int y){
  7. return x > y ? x : y;
  8. }
  9.  
  10. int main() {
  11. int x, y, z;
  12. char str[];
  13. while(scanf("%d %d", &n, &m) != EOF) {
  14. for(siz = ;siz * siz < n;siz ++);
  15. for(int i = ;i <= n / siz;i ++) mmax[i] = ;
  16. for(int i = ;i < n;i ++)
  17. scanf("%d", &a[i]), mmax[i / siz] = max(mmax[i / siz], a[i]);
  18. while(m --) {
  19. scanf("%s %d %d", str, &x, &y);
  20. if(str[] == 'Q') {
  21. z = , x --, y --;
  22. if(x / siz == y / siz) {
  23. for(int i = x;i <= y;i ++)
  24. z = max(z, a[i]);
  25. }
  26. else {
  27. for(int i = x;i < x / siz * siz + siz;i ++)
  28. z = max(z, a[i]);
  29. for(int i = y / siz * siz;i <= y;i ++)
  30. z = max(z, a[i]);
  31. for(int i = x / siz + ;i < y / siz;i ++)
  32. z = max(z, mmax[i]);
  33. }
  34. printf("%d\n", z);
  35. }
  36. else {
  37. x --, a[x] = y, mmax[x / siz] = ;
  38. for(int i = x / siz * siz;i < x / siz * siz + siz;i ++)
  39. mmax[i / siz] = max(mmax[i / siz], a[i]);
  40. }
  41. }
  42. }
  43. }

zkw线段树

  1. #include <cstdio>
  2.  
  3. int n, m, M;
  4. int tr[];
  5.  
  6. int max(int x, int y){
  7. return x > y ? x : y;
  8. }
  9.  
  10. int main() {
  11. int x, y, z;
  12. char str[];
  13. while(scanf("%d %d", &n, &m) != EOF) {
  14. for(M = ;M < n + ;M <<= );
  15. for(int i = M + ;i <= M + n;i ++) scanf("%d", &tr[i]);
  16. for(int i = M + n + ;i <= (M << );i ++) tr[i] = ;
  17. for(int i = M;i >= ;i --) tr[i] = max(tr[i << ], tr[i << | ]);
  18. while(m --) {
  19. scanf("%s %d %d", str, &x, &y);
  20. if(str[] == 'Q') {
  21. z = ;
  22. for(int s = x + M - , t = y + M + ;s ^ t ^ ;s >>= , t >>= ) {
  23. if(~s & ) z = max(z, tr[s ^ ]);
  24. if( t & ) z = max(z, tr[t ^ ]);
  25. }
  26. printf("%d\n", z);
  27. }
  28. else {
  29. for(tr[x += M] = y, x >>= ;x;x >>= )
  30. tr[x] = max(tr[x << ], tr[x << | ]);
  31. }
  32. }
  33. }
  34. }

多组数据的话,基本注意每次都clear一下就好了

另外分块更滋磁下标从0开始计算

但是如果题目明确标号从1-n就要另外注意一下了

E.一个简单的队列套队列,代码供参考

  1. #include <queue>
  2. #include <cstdio>
  3. #include <iostream>
  4.  
  5. #define rep(i, j, k) for(int i = j;i <= k;i ++)
  6.  
  7. using namespace std;
  8.  
  9. queue <int> q, a[];
  10.  
  11. int n, bel[];
  12.  
  13. int main() {
  14. int m, x, t = ;
  15. char str[];
  16. ios::sync_with_stdio(false);
  17. while(cin >> n, n != ) {
  18. printf("Scenario #%d\n", ++ t);
  19. rep(i, , n) {
  20. cin >> m;
  21. rep(j, , m) cin >> x, bel[x] = i;
  22. }
  23. while(cin >> str, str[] != 'S') {
  24. if(str[] == 'E') {
  25. cin >> x;
  26. if(!a[bel[x]].size()) q.push(bel[x]);
  27. a[bel[x]].push(x);
  28. }
  29. else {
  30. printf("%d\n", a[q.front()].front());
  31. a[q.front()].pop();
  32. if(!a[q.front()].size()) q.pop();
  33. }
  34. }
  35. while(!q.empty()) q.pop();
  36. rep(i, , n) while(!a[i].empty()) a[i].pop();
  37. puts("");
  38. }
  39. }

F.无修改区间最值问题,直接上线段树(我写的zkw

  1. #include <cstdio>
  2.  
  3. int n, m, M, tr[][];
  4.  
  5. int min(int x, int y) {
  6. return x < y ? x : y;
  7. }
  8.  
  9. int max(int x, int y) {
  10. return x > y ? x : y;
  11. }
  12.  
  13. int main() {
  14. int s, t, r, l;
  15. scanf("%d %d", &n, &m);
  16. for(M = ;M < n + ; M <<= );
  17. for(int i = M + ;i <= M + n;i ++) scanf("%d", &tr[][i]), tr[][i] = tr[][i];
  18. for(int i = M + n + ;i <= M << ;i ++) tr[][i] = ;
  19. for(int i = M;i;i --)
  20. tr[][i] = max(tr[][i << ], tr[][i << | ]),
  21. tr[][i] = min(tr[][i << ], tr[][i << | ]);
  22. while(m --) {
  23. scanf("%d %d", &s, &t), r = , l = ;
  24. for(s += M - , t += M + ;s ^ t ^ ;s >>= , t >>= ) {
  25. if(~ s & ) r = max(r, tr[][s ^ ]), l = min(l, tr[][s ^ ]);
  26. if( t & ) r = max(r, tr[][t ^ ]), l = min(l, tr[][t ^ ]);
  27. }
  28. printf("%d\n", r - l);
  29. }
  30. return ;
  31. }

G.并查集+堆的启发式合并

总之手写堆大概只是用来理解其原理的

平时写题又不卡常数还是priority_queue大法好啊

顶多撸个简单的 '<' 重载美滋滋

  1. #include <queue>
  2. #include <cstdio>
  3.  
  4. using std::queue;
  5. using std::priority_queue;
  6.  
  7. priority_queue <int> q[];
  8.  
  9. int n, m, f[], a[];
  10.  
  11. void swap(int &x, int &y) {
  12. x ^= y, y ^= x, x ^= y;
  13. }
  14.  
  15. int find_(int x) {
  16. if(f[x] != x) return f[x] = find_(f[x]);
  17. return x;
  18. }
  19.  
  20. int main() {
  21. int x, y, z;
  22. while(scanf("%d", &n) != EOF) {
  23. for(int i = ;i <= n;i ++)
  24. f[i] = i, scanf("%d", &a[i]), q[i].push(a[i]);
  25. scanf("%d", &m);
  26. while(m -- ){
  27. scanf("%d %d", &x, &y);
  28. x = find_(x), y = find_(y);
  29. if(x == y) puts("-1");
  30. else {
  31. if(q[x].size() < q[y].size()) swap(x, y);
  32. z = q[x].top(), q[x].pop(), q[x].push(z >> );
  33. z = q[y].top(), q[y].pop(), q[y].push(z >> );
  34. f[y] = x;
  35. while(!q[y].empty()) q[x].push(q[y].top()), q[y].pop();
  36. printf("%d\n", q[x].top());
  37. }
  38. }
  39. for(int i = ;i <= n;i ++)
  40. while(!q[i].empty()) q[i].pop();
  41. }
  42. }

H.把如何锯木头看成如何拼木头

就是个石子合并问题,或者说哈夫曼树构造问题

  1. #include <iostream>
  2. #include <queue>
  3.  
  4. #define rep(i, j, k) for(int i = j;i <= k;i ++)
  5.  
  6. #define rev(i, j, k) for(int i = j;i >= k;i --)
  7.  
  8. using namespace std;
  9.  
  10. typedef long long ll;
  11.  
  12. priority_queue <ll, vector<ll>, greater<ll> > q;
  13.  
  14. ll ans, a, w;
  15.  
  16. int n;
  17.  
  18. int main() {
  19. ios::sync_with_stdio(false);
  20. cin >> n;
  21. rep(i, , n) cin >> a, q.push(a);
  22. rep(i, , n) w = q.top(), q.pop(), w += q.top(), q.pop(), ans += w, q.push(w);
  23. cout << ans;
  24. return ;
  25. }

I.很裸的并查集

我们用 i 和 i + n 来代表虫 i 的两个相反性别

而如果有 x 和 y 交配,那么显然有

x 和 y + n 为同一性别

y 和 x + n 为同一性别

即 union(x, y + n), union(y, x + n)

所以最终在同一集合中的小虫都必须是同一性别

而如果存在 i,满足 i 和 i + n 在同一个集合中

那么显然存在矛盾了

  1. #include <cstdio>
  2.  
  3. int Case, n, m, f[];
  4.  
  5. int find_(int x) {
  6. if(f[x] != x) return f[x] = find_(f[x]);
  7. return x;
  8. }
  9.  
  10. void union_(int x, int y) {
  11. x = find_(x), y = find_(y);
  12. if(x != y) f[y] = x;
  13. }
  14.  
  15. int main() {
  16. int x, y, ans = ;
  17. scanf("%d", &Case);
  18. for(int t = ;t <= Case;t ++) {
  19. ans = , printf("Scenario #%d:\n", t);
  20. scanf("%d %d", &n, &m);
  21. for(int i = ;i <= n;i ++) f[i] = i, f[i + n] = i + n;
  22. for(int i = ;i <= m;i ++) {
  23. scanf("%d %d", &x, &y);
  24. union_(x, y + n), union_(x + n, y);
  25. }
  26. for(int i = ;i <= n;i ++)
  27. if(find_(i) == find_(i + n)) {
  28. ans = ;
  29. break;
  30. }
  31. puts(ans ? "No suspicious bugs found!\n" : "Suspicious bugs found!\n");
  32. }
  33. return ;
  34. }

J.看图没看题,可能是个单调队列?

K.太长没看

L.对区间们排个序,然后就是个简单的线段树?

M.树状数组查个逆序对啥的

那个不断往后放的操作其实就那样吧

减一下加一下它对逆序对数造成的影响就行了

  1. #include <cstdio>
  2.  
  3. int n, a[], c[];
  4.  
  5. int lowbit(int x) {
  6. return x & (-x);
  7. }
  8.  
  9. void add(int i) {
  10. while(i <= n) c[i] ++, i += lowbit(i);
  11. }
  12.  
  13. int ask(int i) {
  14. int ret = ;
  15. while(i > ) ret += c[i], i -= lowbit(i);
  16. return ret;
  17. }
  18.  
  19. long long sum, ans;
  20.  
  21. int main() {
  22. while(scanf("%d", &n) != EOF) {
  23. sum = ;
  24. for(int i = ;i <= n;i ++) c[i] = ;
  25. for(int i = ;i <= n;i ++)
  26. scanf("%d", &a[i]), a[i] ++, add(a[i]), sum += i - ask(a[i]);
  27. ans = sum;
  28. for(int i = ;i < n;i ++) {
  29. sum += n - - ask(a[i] - ) * ;
  30. if(sum < ans) ans = sum;
  31. }
  32. printf("%lld\n", ans);
  33. }
  34. }

N.map随便做,读入有点恶心就是了

我用的getline,因为直接cin读入string类型会忽略换行和空格

而getline就能读入一行,读入的一行为空的话,会有s[0] = '\0'

也就是读进来一个空串而不会被直接忽略这个空行

  1. #include <map>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. map <string, string> p;
  7.  
  8. string s1, s2, s;
  9.  
  10. int main() {
  11. int i;
  12. ios::sync_with_stdio(false);
  13. while(getline(cin, s), s[] != '\0') {
  14. i = , s1 = "", s2 = "";
  15. while(s[i] != ' ') s1 += s[i ++];i ++;
  16. while(s[i] != '\0') s2 += s[i ++];
  17. p[s2] = s1;
  18. }
  19. while(cin >> s) {
  20. if(p[s] != "") cout << p[s] << endl;
  21. else cout << "eh\n";
  22. }
  23. return ;
  24. }

O.很裸的主席树,离线做有点费脑子?

P.简单题目,自己手算循环节即可

  1. #include<iostream>
  2.  
  3. using namespace std;
  4.  
  5. int a[] = {, , , , , };
  6.  
  7. int main() {
  8. int t;
  9. long long n;
  10. cin >> t;
  11. while(t--) cin >> n, cout << a[n % ] << endl;
  12. return ;
  13. }

=

题后话:

poj真的很老旧了啊

1.bits/stdc++.h 这个全能库不支持

2.ios::sync_with_stdio(false)

取消cin与stdio的同步都不支持

就是加了这句话依旧是cin的速度...

3.G++和C++两个选项很迷

编译标准和运行时间都会有差别...

一个编译过了另一个可能编译不过...

一个提交超时另一个可能就通过了...

BUPT2017 springtraining(16) #2 ——基础数据结构的更多相关文章

  1. BUPT2017 springtraining(16) #4 ——基础数论

    题目在这里 A.手动打表找规律得组合数 n -= 2, m -= 2, ans = C(n, m) #include <bits/stdc++.h> using namespace std ...

  2. BUPT2017 springtraining(16) #1 题解

    https://vjudge.net/contest/162590 A: 不难发现,当L=R时输出L,当L<R时输出2. B: 贪心得配对.1和n配 2和n-1配,对与对直接只要花1个代价就可以 ...

  3. BUPT2017 springtraining(16) #6 ——图论

    题目链接 A.容易发现最后字符的对应都是一对一的 或者说我们没办法出现最后多对一或者一对多的情况 所以只要算出 ‘a’ - 'z' 每个字符最后对应的字符即可 #include <cstdio& ...

  4. BUPT2017 springtraining(16) #3 ——搜索与动态规划

    题目在这里啊 A.最长上升子序列,范围很小所以写了简单的O(n^2)算法 #include <iostream> #define rep(i, j, k) for(int i = j;i ...

  5. BUPT2017 springtraining(16) #1 ——近期codeforces简单题目回顾

    这里是contest 8道题全部来源于 cf 的两场contest (出题人可真懒啊 Codeforces Round #411 (Div. 2)的ABCDE Codeforces Round #40 ...

  6. 理解 OpenStack + Ceph (4):Ceph 的基础数据结构 [Pool, Image, Snapshot, Clone]

    本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...

  7. Numpy基础数据结构 python

    Numpy基础数据结构 NumPy数组是一个多维数组对象,称为ndarray.其由两部分组成: 实际的数据 描述这些数据的元数据 1.一维数组 import numpy as np ar = np.a ...

  8. Flink内存管理源代码解读之基础数据结构

    概述 在分布式实时计算领域,怎样让框架/引擎足够高效地在内存中存取.处理海量数据是一个非常棘手的问题.在应对这一问题上Flink无疑是做得非常杰出的,Flink的自主内存管理设计或许比它自身的知名度更 ...

  9. redis 基础数据结构实现

    参考文献 redis数据结构分析 Skip List(跳跃表)原理详解 redis 源码分析之内存布局 Redis 基础数据结构与对象 Redis设计与实现-第7章-压缩列表 在redis中构建了自己 ...

随机推荐

  1. NOI.AC #31. MST

    好像又是神仙dp....gan了一早上 首先这是个计数类问题,上DP, 对于一个最小生成树,按照kruskal是一个个联通块,枚举边小到大合成的 假如当前边是树边,那么转移应该还是枚举两个块然后合并 ...

  2. 【NYOJ42】一笔画问题

    一笔画问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 Position:http://acm.nyist.net/JudgeOnline/problem.php?pid= ...

  3. 在IIS上搭建WebSocket服务器(二)

    服务器端代码编写 1.新建一个ASP.net Web MVC5项目 2.新建一个“一般处理程序” 3.Handler1.ashx代码如下: using System; using System.Col ...

  4. HDU4336:Card Collector

    题意 有n张卡片,每一次 有pi的概率买到第i张卡.求买到所有卡的期望购买次数. n<=20 解析 Solution 1:大力状压(就是步数除以方案数) #include<iostream ...

  5. Balanced Lineup(线段树)

    http://poj.org/problem?id=3264 题意:n个数,q个询问,输出[l,r]中最大值与最小值的差. #include <stdio.h> #include < ...

  6. 使用php实现二叉搜索树

    看到一位大神写的js的搜索树,自己也按照模式写了一个php的二叉搜索树. <?phpclass node{ public $data; public $key; public $left=nul ...

  7. Unity 代码改宏定义

    两个函数 PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup); //所有宏定义 ; 分割 PlayerSettings.SetS ...

  8. [Swift通天遁地]三、手势与图表-(3)通过捏合手势放大和缩小图像视图

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  9. hadoop一主一从部署(1)

    一.安装前说明 主机IP:192.168.132.128 从机IP:192.168.132.129 1. 所有的安装包我放在了/root/这个目录下,你要根据自己情况去修改,这点必须注意 2. 采用的 ...

  10. Jsoup爬虫获取公司纳税识别号

    天眼查 /** * 根据公司名称获取统一社会信用代码 * * @author xiaofei.xian 日期:2019年3月20日 上午11:12:41 */ public class GetTaxN ...