A. Vladik and Courtesy

水题略过

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cmath>
  4. using namespace std;
  5. typedef long long int LL;
  6. int main()
  7. {
  8. LL a,b;
  9. scanf("%I64d%I64d",&a,&b);
  10. LL num=1;
  11. while(true)
  12. {
  13. if(a<num){printf("Vladik\n");return 0;}
  14. a-=num;
  15. //b+=num;
  16. num++;
  17. if(b<num){printf("Valera\n");return 0;}
  18. b-=num;
  19. //a+=num;
  20. num++;
  21. }
  22. return 0;
  23. }

B. Vladik and Complicated Book

给定一个序列, 询问子区间【l,r】的第k小数是不是原位置的数。

显然可以用主席树维护,不过这道题数据放水了,用暴力一点的方法应该也能过。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N = 100000 + 5;
  6.  
  7. int a[N], b[N], rt[N * 20], ls[N * 20], rs[N * 20], sum[N * 20],numm[N];
  8.  
  9. int n, k, tot, sz, ql, qr, x, q, T;
  10.  
  11. void Build(int& o, int l, int r){
  12. if(l>r)return ;
  13. o = ++ tot;
  14. sum[o] = 0;
  15. if(l == r) return;
  16. int m = (l + r) >> 1;
  17. Build(ls[o], l, m);
  18. Build(rs[o], m + 1, r);
  19. }
  20.  
  21. void update(int& o, int l, int r, int last, int p){
  22. o = ++ tot;
  23. ls[o] = ls[last];
  24. rs[o] = rs[last];
  25. sum[o] = sum[last] + 1;
  26. if(l == r) return;
  27. int m = (l + r) >> 1;
  28. if(p <= b[m]) update(ls[o], l, m, ls[last], p);
  29. else update(rs[o], m + 1, r, rs[last], p);
  30. }
  31.  
  32. int query(int ss, int tt, int l, int r, int k){
  33. if(l == r) return l;
  34. int m = (l + r) >> 1;
  35. int cnt = sum[ls[tt]] - sum[ls[ss]];
  36. if(k <= cnt) return query(ls[ss], ls[tt], l, m, k);
  37. else return query(rs[ss], rs[tt], m + 1, r, k - cnt);
  38. }
  39.  
  40. void work(){
  41. scanf("%d%d%d", &ql, &qr, &x);
  42. int xx=x;
  43. x=(xx-ql+1);
  44. int ans = query(rt[ql - 1], rt[qr], 1, sz, x);
  45. if(b[ans]==numm[xx])printf("Yes\n");
  46. else printf("No\n");
  47. }
  48.  
  49. int main(){//freopen("t.txt","r",stdin);
  50. T=1;
  51. while(T--){
  52. scanf("%d%d", &n, &q);
  53. for(int i = 1; i <= n; i ++) scanf("%d", a + i), numm[i]=b[i] = a[i];
  54. sort(b + 1, b + n + 1);
  55. sz = unique(b + 1, b + n + 1) - (b + 1);
  56. tot = 0;
  57. Build(rt[0],1, sz);
  58. //for(int i = 0; i <= 4 * n; i ++)printf("%d,rt = %d,ls = %d, rs = %d, sum = %d\n", i, rt[i], ls[i], rs[i], sum[i]);
  59. //for(int i = 1; i <= n; i ++)a[i] = lower_bound(b + 1, b + sz + 1, a[i]) - b;
  60. for(int i = 1; i <= n; i ++)update(rt[i], 1, sz, rt[i - 1], a[i]);
  61. // for(int i = 0; i <= 5 * n; i ++)printf("%d,rt = %d,ls = %d, rs = %d, sum = %d\n", i, rt[i], ls[i], rs[i], sum[i]);
  62. while(q --)work();
  63. }
  64. return 0;
  65. }

C. Vladik and Memorable Trip

O(n^2)的线性dp 不要想太多。。(我都想到DAG去了。。。)

代码比较简单,可以直接看懂。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. vector <int> ps [5010], cs[5010];
  5. int s[5010] , e[5010];
  6. bool vis[5010];
  7. long long dp [5010];
  8. int main()
  9. {
  10. int n;
  11. scanf("%d",&n);
  12. vector <int> a (n);
  13. for (int i = 0; i < n; i++) {
  14. scanf("%d",&a[i]);
  15. if (!vis[a[i]]) s[a[i]] = i;
  16. vis[a[i]] = 1;
  17. e[a[i]] = i;
  18. }
  19. for (int i = 0; i < n; i++) vis[a[i]] = 0;
  20. for (int i = 0; i < n; i++) {
  21. int mx = i, rx = 0, lj = i;
  22. for (int j = i; j < n; j++) {
  23. if (s[a[j]] < i) break;
  24. lj = j;
  25. mx = max(mx,e[a[j]]);
  26. if (!vis[a[j]]) rx ^= a[j];
  27. vis[a[j]] = 1;
  28.  
  29. if (mx <= j) {
  30. ps[i].push_back(j);
  31. cs[i].push_back(rx);
  32. }
  33. }
  34. for (int k = lj; k >= i; k--) vis[a[k]] = 0;
  35. }
  36. for (int i = n-1; i >= 0; i--) {
  37. dp[i] = dp[i+1];
  38. for (int j = 0; j < ps[i].size(); j++) {
  39. dp[i] = max(dp[i],dp[ps[i][j]+1]+cs[i][j]);
  40. }
  41. }
  42. printf("%I64d\n",dp[0]);
  43. }

D. Vladik and Favorite Game

第一步判断一下按钮是否反转即可。剩下的直接暴力求路径,水题。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define mp make_pair
  4. #define ff first
  5. #define ss second
  6. #define pb push_back
  7.  
  8. const int N = 100 + 11;
  9.  
  10. int use[N][N];
  11. char a[N][N],b[5];
  12. vector<pair<int,int> > v,w;
  13. vector<int> vv;
  14.  
  15. void dfs(int l, int r)
  16. {
  17. use[l][r]=1;
  18. v.pb(mp(l,r));
  19. if (a[l][r]=='F') {w=v; return;}
  20. if (use[l-1][r]==0&&(a[l-1][r]=='.'||a[l-1][r]=='F')) dfs(l-1,r);
  21. if (use[l+1][r]==0&&(a[l+1][r]=='.'||a[l+1][r]=='F')) dfs(l+1,r);
  22. if (use[l][r-1]==0&&(a[l][r-1]=='.'||a[l][r-1]=='F')) dfs(l,r-1);
  23. if (use[l][r+1]==0&&(a[l][r+1]=='.'||a[l][r+1]=='F')) dfs(l,r+1);
  24. v.pop_back();
  25. }
  26. int main()
  27. {
  28. int n,m;
  29. cin>>n>>m;
  30. int l,r;
  31. for (int i=1; i<=n; i++)
  32. for (int j=1; j<=m; j++)
  33. {
  34. cin>>a[i][j];
  35. if (a[i][j]=='F') {l=i; r=j;}
  36. }
  37. b[1]='L';
  38. b[2]='R';
  39. b[3]='U';
  40. b[4]='D';
  41. dfs(1,1);
  42. for (int i=1; i<w.size(); i++)
  43. {
  44. if (w[i].ff==w[i-1].ff)
  45. {
  46. if (w[i].ss==w[i-1].ss-1) vv.pb(1); else vv.pb(2);
  47. } else
  48. if (w[i].ff==w[i-1].ff-1) vv.pb(3); else vv.pb(4);
  49. }
  50. int u1=0,u2=0;
  51. int x=1,y=1;
  52. for (int i=0; i<vv.size(); i++)
  53. {
  54. if (vv[i]==2&&u1==0)
  55. {
  56. cout<<"R"<<endl;
  57. int xx,yy;
  58. cin>>xx>>yy;
  59. u1=1;
  60. if (x==xx&&y==yy) {swap(b[1],b[2]); cout<<"L"<<endl; cin>>x>>y;}
  61. } else
  62. if (vv[i]==4&&u2==0)
  63. {
  64. cout<<"D"<<endl;
  65. int xx,yy;
  66. cin>>xx>>yy;
  67. u2=1;
  68. if (x==xx&&y==yy) {swap(b[3],b[4]); cout<<"U"<<endl; cin>>x>>y;}
  69. } else
  70. {
  71. cout<<b[vv[i]]<<endl;
  72. cin>>x>>y;
  73. }
  74. }
  75.  
  76. }

  

E. Vladik and Entertaining Flags

线段树+并查集

给定一个行数为10 列数10w的矩阵,每个方块是一个整数, 给定l和r 求范围内的联通块数量 所谓联通块即数字相等。

考虑用二分的方法合并两个联通块,在合并的时候只需要标记边界的元素属于哪个块即可,不用考虑块内的元素,因为它们不会在将来的合并中使用到。

这样我们就可以做到在常数时间内合并两个块了,这样用线段树维护就没有问题了。

其实想了一下,用倍增的方法也是可以的,dp[i][k]表示从第i列开始 连续2^k列的联通块,复杂度也是O(nlogn)

所以用一个线段树维护所有的[l,r]子块,每次查询线段树即可,合并的时候要重新标号。

重点:对于每个子块,我们只需要知道边界上的元素属于这个子块的哪个联通分量即可(使用并查集维护)

比赛的时候我也是老想块中的元素怎么维护,就觉得二分难搞了,其实完全不需要考虑。。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int N = 10;
  6. const int M = 100010;
  7.  
  8. int n, m, q;
  9. int a[N][M];
  10. int state[50], mark[50];
  11.  
  12. struct Info{
  13. int cnt;
  14. int left[N];
  15. int right[N];
  16.  
  17. Info() {
  18. cnt = 0;
  19. memset(left, 0, sizeof left);
  20. memset(right, 0, sizeof right);
  21. }
  22. } tr[M << 2];
  23.  
  24. Info join(Info &u, Info &v, int p) {
  25. Info f;
  26. f.cnt = u.cnt + v.cnt;
  27. memset(state, 0, sizeof state);
  28. for (int k = 0; k < n; k++) {
  29. if (a[k][p] == a[k][p + 1]) {
  30. int x = u.right[k];
  31. int y = v.left[k] + 21;
  32. while (state[x]) {
  33. x = state[x];
  34. }//路径压缩
  35. while (state[y]) {
  36. y = state[y];
  37. }
  38. if (x != y) {
  39. f.cnt--;
  40. state[y] = x;
  41. }
  42. }
  43. }
  44. int g = 1;
  45. memset(mark, 0, sizeof mark);
  46. for (int k = 0; k < n; k++) {
  47. int x = u.left[k];
  48. while (state[x]) {
  49. x = state[x];
  50. }
  51. if (mark[x] == 0) {
  52. mark[x] = g++;
  53. }//从头标号 只需记录左边界和右边界
  54. f.left[k] = mark[x];//重新标记边界
  55. int y = v.right[k] + 21;
  56. while (state[y]) {
  57. y = state[y];
  58. }
  59. if (mark[y] == 0) {
  60. mark[y] = g++;
  61. }
  62. f.right[k] = mark[y];//重新标记边界
  63. }
  64. return f;
  65. }
  66.  
  67. void build(int l, int r, int i) {
  68. if (l == r) {
  69. for (int k = 0; k < n; k++) {
  70. if (k == 0 || a[k][l] != a[k - 1][l]) {
  71. tr[i].left[k] = tr[i].right[k] = ++tr[i].cnt;
  72. } else {
  73. tr[i].left[k] = tr[i].right[k] = tr[i].left[k - 1];
  74. }
  75. }
  76. } else {
  77. int mid = (l + r) >> 1;
  78. build(l, mid, i + i);
  79. build(mid + 1, r, i + i + 1);
  80. tr[i] = join(tr[i + i], tr[i + i + 1], mid);
  81. }
  82. /*
  83. cout << " + " << l << " " << r << "\n";
  84. for (int k = 0; k < n; k++) {
  85. cout << tr[i].left[k] << " ";
  86. }
  87. cout << "\n";
  88. for (int k = 0; k < n; k++) {
  89. cout << tr[i].right[k] << " ";
  90. }
  91. cout << "\n";
  92. */
  93. }
  94.  
  95. void get(int l, int r, int x, int y, int i, Info &res) {
  96. if (x <= l && r <= y) {
  97. if (l == x) {
  98. res = tr[i];
  99. } else {
  100. res = join(res, tr[i], l - 1);
  101. }
  102. } else {
  103. int mid = (l + r) >> 1;
  104. if (mid >= x) {
  105. get(l, mid, x, y, i + i, res);
  106. }
  107. if (mid < y) {
  108. get(mid + 1, r, x, y, i + i + 1, res);
  109. }
  110. }
  111. }
  112.  
  113. int main() {
  114. scanf("%d %d %d", &n, &m, &q);
  115. for (int i = 0; i < n; i++) {
  116. for (int j = 1; j <= m; j++) {
  117. scanf("%d", &a[i][j]);
  118. }
  119. }
  120. build(1, m, 1);
  121. Info res;
  122. while (q--) {
  123. int l, r;
  124. scanf("%d %d", &l, &r);
  125. get(1, m, l, r, 1, res);
  126. printf("%d\n", res.cnt);
  127. }
  128. }

  

codeforces round 416 div2 补题 CF 811 A B C D E的更多相关文章

  1. codeforces round 422 div2 补题 CF 822 A-F

    A I'm bored with life 水题 #include<bits/stdc++.h> using namespace std; typedef long long int LL ...

  2. codeforces round 421 div2 补题 CF 820 A-E

    A Mister B and Book Reading  O(n)暴力即可 #include<bits/stdc++.h> using namespace std; typedef lon ...

  3. Codeforces round 419 div2 补题 CF 816 A-E

    A Karen and Morning 水题 注意进位即可 #include<bits/stdc++.h> using namespace std; typedef long long i ...

  4. codeforces round 418 div2 补题 CF 814 A-E

    A An abandoned sentiment from past 水题 #include<bits/stdc++.h> using namespace std; int a[300], ...

  5. codeforces round 417 div2 补题 CF 812 A-E

    A Sagheer and Crossroads 水题略过(然而被Hack了 以后要更加谨慎) #include<bits/stdc++.h> using namespace std; i ...

  6. codeforces round 420 div2 补题 CF 821 A-E

    A Okabe and Future Gadget Laboratory 暴力 #include<bits/stdc++.h> using namespace std; typedef l ...

  7. Educational Codeforces Round 23 A-F 补题

    A Treasure Hunt 注意负数和0的特殊处理.. 水题.. 然而又被Hack了 吗的智障 #include<bits/stdc++.h> using namespace std; ...

  8. codeforces 447 A-E div2 补题

    A DZY Loves Hash 水题 #include<iostream> #include<cstdio> #include<cstdlib> #include ...

  9. codeforces round #416 div2

    A:暴力模拟 #include<bits/stdc++.h> using namespace std; int a, b; int main() { scanf("%d%d&qu ...

随机推荐

  1. Matlab学习笔记(四)

    二.MATLAB基础知识 (六)字符串 字符串的创建和简单操作 用单引号对括起来的一系列字符的组合,每个字符是一个元素,通常通过两个字节来存储 表2-22    字符串常见操作函数(e_two_37. ...

  2. 【Codeforces 444A】DZY Loves Physics

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 两个点的子图他们的"密度"是比所有联通生成子图都要大的 "只要胆子大,遇到什么问题都不怕!" [代码] ...

  3. 587. Erect the Fence

    Problem statement: There are some trees, where each tree is represented by (x,y) coordinate in a two ...

  4. TensorFlow-GPU环境配置之一——安装Ubuntu双系统

    本机已经安装过Windows系统,准备安装Ubuntu双系统进行TensorFlow相关工作,需要在windows中将磁盘分出一定空间供Ubuntu使用 1.首先下载Ubuntu17.04版本ISO ...

  5. pymongo collection.save 问题

    项目中有这样一个需求,把路由器信息存入mongo,DB的结构如下: { router_name: name, router_ip: ip, interfaces: [ {oid:1,name:if1} ...

  6. Rust 1.7.0 macro宏的复用 #[macro_use]的使用方法

    Rust 1.7.0 中的宏使用范围包含三种情况: 第一种情况是宏定义在当前文件里.这个文件可能是 crate 默认的 module,也可能是随意的 module 模块. 另外一种情况是宏定义在当前 ...

  7. android动态控制组件的位置、大小和新的动画

    一.动态设置组件的位置 当中view是须要改变位置的控件,top是须要设制的位置: private static void setLayoutX(View view,int top)  { //克隆v ...

  8. boost::mpl::eval_if的使用方法

    近期看boost的时候总是遇见这个eval_if,不知道啥意思,就没法看下去了,比方 前篇文章boost::serialization 拆分serialize函数分析时就出现这样一段代码: templ ...

  9. 公用表表达式(CTE)

    公用表表达式(CTE,Common table expression)是和派生表很相似的另一种形式的表表达式,而且具有一些重要优势.CTE 是在 SQL Server 2005 中引入的,是ANSI ...

  10. 打开google 新地址

    还在为谷歌打不开而发愁吗? 那就试试这个吧 91.213.30.151