A: Little Sub and Pascal's Triangle

Solved.

题意:

求杨辉三角第n行奇数个数

思路:

薛聚聚说找规律,16说Lucas

答案是 $2^p \;\;p 为 n - 1 中 以2进制表示下1的个数$

证明

$Ans = \sum\limits_0^n C_n^i \;\%\; 2 = \sum\limits_0^n C_{\frac{n}{2}}^{\frac{i}{2}} \cdot C_{n\;\%\;2}^{i\;\%\;2}$

我们考虑 $C_{n \;\%\; 2}^{i \;\%\; 2}$ 一共有四种取值

$C_0^0 \;\; C_0^1\;\; C_1^0 \;\; C_1^1$

我们发现 只有 $C_0^1的值为0 其他三个值都为1$

那么我们再考虑$C_n^i 这个式子$

它通过卢卡斯定理分解 实际上可以写成

我们先假设

$i 以二进制表示为$

$a_1, a_2, \cdots a_k$

$n 以二进制表示为$

$b_1, b_2, \cdots b_k$

那么 $C_n^i = C_{b_1}^{a_1} \cdot C_{b_2}^{a_2} \cdots C_{b_k}^{a_k}$

那么我们发现,

要满足$C_n^i\;\%\; 2 = 1 \;\;$

$那么在b_y = 1的位置上,i在对应位置上取0或者1都可以$

在$b_y = 0 的位置上,i在对应位置的取值已经固定 是 0$

那么$i的取值一共有2^p  p 为(n - 1)以2进制表示下1的个数$

为什么是$n - 1 \;\;因为杨辉三角是从第0行开始的$

  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6.  
  7. ll n;
  8.  
  9. int main()
  10. {
  11. int t;
  12. scanf("%d", &t);
  13. while(t--)
  14. {
  15. scanf("%lld", &n);
  16. n--;
  17. ll tmp = ;
  18. while(n)
  19. {
  20. if(n & ) tmp++;
  21. n >>= ;
  22. }
  23. ll ans = 1ll << tmp;
  24. printf("%lld\n", ans);
  25. }
  26. return ;
  27. }

B:Little Sub and his Geometry Problem

Solved.

题意:

一个点的权值定义为它到左下角所有点的曼哈顿距离

q次查询, 每次查询权值为c的点的个数

思路:

$给出的点沿着x轴正方向, y轴正方向都是严格单调递增的。$

$因此可以枚举x轴, 动态维护左下角点个数以及权值, 向右走的同时$

$将横坐标相同, 纵坐标<=当前位置的点假如, 向下走的时候将纵坐标相同给的点移除$

$当前权值为c时 ans++$

(薛聚聚:不会写题解啊)

  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef unsigned long long ull;
  7.  
  8. const double eps = 1e-;
  9. const ll MOD = 1e9 + ;
  10. const ll INFLL = 0x3f3f3f3f3f3f3f3f;
  11. const int INF = 0x3f3f3f3f;
  12. const int maxn = 1e5 + ;
  13.  
  14. int n, k;
  15. ll sum, cnt;
  16. ll sum_arr[maxn], cnt_arr[maxn];
  17. ll ans[];
  18.  
  19. struct node {
  20. int x, y;
  21. node() {}
  22. node(int x, int y) :x(x), y(y) {}
  23. bool operator < (const node &other) const
  24. {
  25. return x == other.x ? y < other.y : x < other.x;
  26. }
  27. }P[maxn];
  28.  
  29. ll solve(ll c)
  30. {
  31. cnt = sum = ;
  32. memset(sum_arr, , sizeof sum_arr);
  33. memset(cnt_arr, , sizeof cnt_arr);
  34. int index = ;
  35. int ans = ;
  36. int y = n;
  37. for (int x = ; x <= n; ++x)
  38. {
  39. while (index <= k && P[index].x <= x)
  40. {
  41. if (P[index].y <= y)
  42. {
  43. cnt++;
  44. sum += P[index].x + P[index].y;
  45. sum_arr[P[index].y] += P[index].x + P[index].y;
  46. cnt_arr[P[index].y]++;
  47. }
  48. ++index;
  49. }
  50. while ((x + y) * cnt - sum > c)
  51. {
  52. sum -= sum_arr[y];
  53. cnt -= cnt_arr[y];
  54. --y;
  55. }
  56. if ((x + y) * cnt - sum == c) ++ans;
  57. }
  58. return ans;
  59. }
  60.  
  61. void RUN()
  62. {
  63. int t;
  64. scanf("%d", &t);
  65. while (t--)
  66. {
  67. scanf("%d %d", &n, &k);
  68. for (int i = ; i <= k; ++i) scanf("%d %d", &P[i].x, &P[i].y);
  69. sort(P + , P + + k);
  70. int q;
  71. scanf("%d", &q);
  72. for (int i = ; i <= q; ++i)
  73. {
  74. ll c;
  75. scanf("%lld\n", &c);
  76. ans[i] = solve(c);
  77. }
  78. for (int i = ; i <= q; ++i) printf("%lld%c", ans[i], " \n"[i == q]);
  79. }
  80. }
  81.  
  82. int main()
  83. {
  84. #ifdef LOCAL_JUDGE
  85. freopen("Text.txt", "r", stdin);
  86. #endif // LOCAL_JUDGE
  87.  
  88. RUN();
  89.  
  90. #ifdef LOCAL_JUDGE
  91. fclose(stdin);
  92. #endif // LOCAL_JUDGE
  93. return ;
  94. }

E:Little Sub and Mr.Potato's Math Problem

Solved.

题意:

给出n, k

将n个数按照字典序排序, k所在的位置为m

现在给出k, m  求最小的n

思路:

当k为10的整数倍, 那么它一定在第$log_{10^k}$

$随后统计当n=k的时候, 排在k前面的个数,和m比较, 判断是否合法$

$接着不断增加n, 统计每次增长排在k前面的个数, 随后输出n$

(薛聚聚:不会写题解啊)

  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef unsigned long long ull;
  7.  
  8. const double eps = 1e-;
  9. const ll MOD = 1e9 + ;
  10. const ll INFLL = 0x3f3f3f3f3f3f3f3f;
  11. const int INF = 0x3f3f3f3f;
  12. const int maxn = 1e5 + ;
  13.  
  14. ll k, m;
  15. int arr[maxn];
  16. ll pow_10[];
  17.  
  18. void Init()
  19. {
  20. pow_10[] = ;
  21. for (int i = ; i <= ; ++i)
  22. {
  23. pow_10[i] = pow_10[i - ] * ;
  24. }
  25. }
  26.  
  27. void solve()
  28. {
  29. ll num = ;
  30. for (int i = ;; ++i)
  31. {
  32. if (num > k) break;
  33. else if (num == k)
  34. {
  35. if (i == m)
  36. {
  37. printf("%lld\n", k);
  38. return;
  39. }
  40. else
  41. {
  42. puts("");
  43. return;
  44. }
  45. }
  46. num *= ;
  47. }
  48. int len = ;
  49. num = k;
  50. while (num)
  51. {
  52. arr[++len] = num % ;
  53. num /= ;
  54. }
  55. reverse(arr + , arr + + len);
  56. ll ans = ;
  57. num = ;
  58. for (int i = ; i <= len; ++i)
  59. {
  60. num = num * + arr[i];
  61. ans += num - pow_10[i - ];
  62. if (i != len) ++ans;
  63. }
  64. if (ans >= m)
  65. {
  66. puts("");
  67. return;
  68. }
  69. else if (ans == m - )
  70. {
  71. printf("%lld\n", k);
  72. return;
  73. }
  74. while ()
  75. {
  76. len++;
  77. num *= ;
  78. if (ans + num - pow_10[len - ] >= m - )
  79. {
  80. ans = pow_10[len - ] + m - ans - ;
  81. printf("%lld\n", ans);
  82. return;
  83. }
  84. ans += num - pow_10[len - ];
  85. }
  86. }
  87.  
  88. void RUN()
  89. {
  90. Init();
  91. int t;
  92. scanf("%d", &t);
  93. while (t--)
  94. {
  95. scanf("%lld %lld", &k, &m);
  96. solve();
  97. }
  98. }
  99.  
  100. int main()
  101. {
  102. #ifdef LOCAL_JUDGE
  103. freopen("Text.txt", "r", stdin);
  104. #endif // LOCAL_JUDGE
  105.  
  106. RUN();
  107.  
  108. #ifdef LOCAL_JUDGE
  109. fclose(stdin);
  110. #endif // LOCAL_JUDGE
  111. return ;
  112. }

F:Little Sub and a Game

Unsolved.

题意:

有两个玩家$A, B 刚开始有一个变量v = 0$

$A玩家有N个pair, B玩家有M个pair \;\; pair 为(x, y) A玩家N次操作,每次选择x_i 或者 y_i 来异或v B玩家有M次操作$

$A玩家先进行N次操作, B玩家再进行M次操作$

A玩家想让$v尽量大,B玩家想让v尽量小$

两个玩家都采用最优策略,求最后$v$的值

G:Little Sub and Tree

Solved.

题意:

给出一个无根树,选取$k个点对所有点进行编码$

按如下方式进行编码

$令选取的k个点为 s_1, s_2 \cdots s_k$

编出的码有$k位$

$对于u来说,第i位的编码为 s_i -> u的简单路径上的点的总数$

思路:

如果是一条链的话  那么取两端的一个就可以了

那么我们考虑一棵树中,如果某个节点的儿子对应的子树是一条链

那么这条链是可以被缩点成一个叶节点 而对答案没有影响

那么现在树就被我们简化成了 只有叶节点的子树

首先注意到,一棵子树内节点的区分和这棵子树外的点的选取是没有关系的

那么我们考虑 一个点对应的儿子当中,如果有$x个叶节点$

那么这x个节点要想被区分,就需要取$x - 1$ 个

再考虑一个点的儿子对应的子树,如果子树内都被区分了,那么合并起来也是被区分的

那么考虑选谁作为根

只要根不在链上就可以了,因为如果在链上会对缩点产生影响

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define N 100010
  5. int t, n, root, d[N], fa[N];
  6. vector <int> G1[N], G2[N], res;
  7.  
  8. int pre(int u)
  9. {
  10. int id = -;
  11. int cnt = G1[u].size() - ;
  12. if (cnt == ) return u;
  13. for (auto v : G1[u]) if (v != fa[u])
  14. {
  15. fa[v] = u;
  16. id = pre(v);
  17. G2[u].push_back(id);
  18. }
  19. if (cnt == && u != root) return id;
  20. else return u;
  21. }
  22.  
  23. void DFS(int u)
  24. {
  25. int need = ;
  26. for (auto v : G2[u]) if (v != fa[u] && !d[v])
  27. ++need;
  28. --need;
  29. for (auto v : G2[u]) if (v != fa[u])
  30. {
  31. fa[v] = u;
  32. if (!d[v] && need > )
  33. {
  34. --need;
  35. res.push_back(v);
  36. }
  37. DFS(v);
  38. }
  39. }
  40.  
  41. int main()
  42. {
  43. scanf("%d", &t);
  44. while (t--)
  45. {
  46. scanf("%d", &n);
  47. for (int i = ; i <= n; ++i)
  48. {
  49. G1[i].clear();
  50. G2[i].clear();
  51. d[i] = -;
  52. fa[i] = ;
  53. }
  54. res.clear();
  55. root = -;
  56.  
  57. for (int i = , u, v; i < n; ++i)
  58. {
  59. scanf("%d%d", &u, &v);
  60. G1[u].push_back(v);
  61. G1[v].push_back(u);
  62. ++d[u]; ++d[v];
  63. }
  64. if (n == )
  65. {
  66. puts("1\n1");
  67. continue;
  68. }
  69. for (int i = ; i <= n; ++i) if (d[i] > )
  70. {
  71. root = i;
  72. break;
  73. }
  74. if(root == -)
  75. {
  76. int ans = ;
  77. for(int i = ; i <= n; ++i) if(d[i] == ) ans = i;
  78. printf("1\n%d\n", ans);
  79. continue;
  80. }
  81. pre(root);
  82. DFS(root);
  83. //puts("bug");
  84. //for (int i = 1; i <= n; ++i) printf("%d %d\n", i, fa[i]);
  85. //puts("bug");
  86. int k = res.size();
  87. printf("%d\n", k);
  88. for (int i = ; i < k; ++i) printf("%d%c", res[i], " \n"[i == k - ]);
  89. }
  90. return ;
  91. }

I:Little Sub and Isomorphism Sequences

Solved.

题意:

有一个$A[], 两种操作$

  • $A_x -> y$
  • 查询最长同构子串

思路:

考虑最长同构子串肯定会有重叠部分,那么两端出去的部分就是不同的部分

那么这个不同的部分让它长度为1即可,因为多余的长度是没有用的

那么题意就可以转化为 找一个最长的子串,使得两端相同即可

将数据离散化 开2e5个set维护每个数的位置

然后用数据结构 维护答案的最大值 即可

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define N 200010
  5. int t, n, m, a[N], b[N];
  6. struct qnode
  7. {
  8. int op, x, y;
  9. void scan()
  10. {
  11. scanf("%d", &op);
  12. if (op == )
  13. {
  14. scanf("%d%d", &x, &y);
  15. b[++b[]] = y;
  16. }
  17. }
  18. }q[N];
  19. set <int> s[N];
  20. namespace SEG
  21. {
  22. int a[N << ];
  23. void build(int id, int l, int r)
  24. {
  25. a[id] = -;
  26. if (l == r) return;
  27. int mid = (l + r) >> ;
  28. build(id << , l, mid);
  29. build(id << | , mid + , r);
  30. }
  31. void update(int id, int l, int r, int pos, int v)
  32. {
  33. if (l == r)
  34. {
  35. a[id] = v;
  36. return;
  37. }
  38. int mid = (l + r) >> ;
  39. if (pos <= mid) update(id << , l, mid, pos, v);
  40. else update(id << | , mid + , r, pos, v);
  41. a[id] = max(a[id << ], a[id << | ]);
  42. }
  43. }
  44. void Hash()
  45. {
  46. sort(b + , b + + b[]);
  47. b[] = unique(b + , b + + b[]) - b - ;
  48. for (int i = ; i <= n; ++i) a[i] = lower_bound(b + , b + + b[], a[i]) - b;
  49. for (int i = ; i <= m; ++i) if (q[i].op == ) q[i].y = lower_bound(b + , b + + b[], q[i].y) - b;
  50. }
  51.  
  52. int main()
  53. {
  54. scanf("%d", &t);
  55. while (t--)
  56. {
  57. scanf("%d%d", &n, &m);
  58. SEG::build(, , n + m);
  59. for (int i = ; i <= n + m; ++i) s[i].clear(); b[] = ;
  60. for (int i = ; i <= n; ++i) scanf("%d", a + i), b[++b[]] = a[i];
  61. for (int i = ; i <= m; ++i) q[i].scan(); Hash();
  62. for (int i = ; i <= n; ++i) s[a[i]].insert(i);
  63. for (int i = ; i <= n + m; ++i) if (s[i].size() >= )
  64. SEG::update(, , n + m, i, *s[i].rbegin() - *s[i].begin());
  65. for (int i = ; i <= m; ++i)
  66. {
  67. if (q[i].op == )
  68. {
  69. int v = a[q[i].x], x = q[i].x, y = q[i].y;
  70. s[v].erase(x);
  71. SEG::update(, , n + m, v, s[v].size() >= ? *s[v].rbegin() - *s[v].begin() : -);
  72. a[q[i].x] = y;
  73. v = y;
  74. s[v].insert(x);
  75. SEG::update(, , n + m, v, s[v].size() >= ? *s[v].rbegin() - *s[v].begin() : -);
  76. }
  77. else printf("%d\n", SEG::a[]);
  78. }
  79. }
  80. return ;
  81. }

ZOJ Monthly, January 2019的更多相关文章

  1. ZOJ Monthly, January 2019 Little Sub and his Geometry Problem 【推导 + 双指针】

    传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5861 Little Sub and his Geometry Prob ...

  2. ZOJ Monthly, January 2019 Little Sub and Isomorphism Sequences 【离线离散化 + set + multiset】

    传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5868 Little Sub and Isomorphism Seque ...

  3. ZOJ Monthly, January 2019 Little Sub and his Geometry Problem ZOJ4082(模拟 乱搞)

    在一次被自己秀死... 飞机 题目: 给出N,K, Q; 给出一个N*N的矩阵  , 与K个特殊点 , 与Q次查询 , 每次查询给出一个C , 问 在这个N*N矩阵中 , 有多少的点是满足这样的一个关 ...

  4. ZOJ Monthly, January 2019 I Little Sub and Isomorphism Sequences(set 妙用) ZOJ4089

    写这篇博客来证明自己的愚蠢 ...Orz  飞机 题意:给定你个数组,以及一些单点修改,以及询问,每次询问需要求得,最长的字串长度,它在其他位置存在同构 题解:经过一些奇思妙想后 ,你可以发现问题是传 ...

  5. ZOJ Monthly, January 2018 训练部分解题报告

    A是水题,此处略去题解 B - PreSuffix ZOJ - 3995 (fail树+LCA) 给定多个字符串,每次询问查询两个字符串的一个后缀,该后缀必须是所有字符串中某个字符串的前缀,问该后缀最 ...

  6. matrix_2015_1 138 - ZOJ Monthly, January 2015

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3844 第一个,n个数,每次操作最大数和最小数都变成他们的差值,最后n个数相 ...

  7. ZOJ Monthly, January 2018

    A 易知最优的方法是一次只拿一颗,石头数谁多谁赢,一样多后手赢 #include <map> #include <set> #include <ctime> #in ...

  8. ZOJ Monthly, January 2018 Solution

    A - Candy Game 水. #include <bits/stdc++.h> using namespace std; #define N 1010 int t, n; int a ...

  9. ZOJ Monthly, January 2019-Little Sub and Pascal's Triangle

    这个题的话,它每行奇数的个数等于该行行号,如果是0开始的,就该数的二进制中的1的个数,设为k,以它作为次数,2k就是了. #include <stdio.h> int main() { i ...

随机推荐

  1. Android中SurfaceView用法示例

    SurfaceView在游戏开发中有着举足轻重的地位,它对于画面的控制有着更大的自由度(不像View要用handler来更新,关于View的),但这方面的参考资料并不是太多,能找到的例子都有点喧宾夺主 ...

  2. python2.0_s12_day19_前端结合后端展示客户咨询纪录

    接下来就是将后台视图与前端页面结合起来了完成后台系统了.实现前端展示用户列表1.先在base.html代码中把模版中Dashboard下面的内容清空,如下: 具体删除哪些html代码,自己找吧.2.我 ...

  3. centos无法联网解决方法

    1)进入 /etc/sysconfig/network-scripts/ 2)vi 或 vim 打开 ifcfg-eth0(不一定是eth0,这个自己判断了) 3)将 ONBOOT=no 改成 ONB ...

  4. 百度地图sdk问题 error inflating class com.baidu.mapapi.map.mapview

    最近在封装开发中,有机会遇到问题还是记录下吧 但是其实都是一个原因  就是 初始化 在MyAplication  onCreate()中加入 SDKInitializer.initialize(get ...

  5. Android SDK更新下载失败以及Studio首次安装取消自动下载SDK

    这是因为,此时Android Studio会去获取 android sdk 组件信息,这个过程相当慢,还经常加载失败,导致Android Studio启动不起开. 解决办法: 不去获取android ...

  6. 浅谈Nutch插件机制(含开发实例)

    plugin(插件)为nutch提供了一些功能强大的部件,举个例子,HtmlParser就是使用比较普遍的用来分析nutch抓取的html文件的插件. 为什么nutch要使用这样的plugin系统? ...

  7. 在centos命令行下安装软件

    考虑到用linux纯命令行模式时,通常都是用作服务器,所以,一般主要是安装一个php.mysql.apache的集成环境和ftp服务器,在这里用xampp集成包即可解决所有问题,在这里说一下我自己的做 ...

  8. 【ecshop】如何解决DEPRECATED: PREG_REPLACE()报错

    部署的ecshop  在高版本的PHP环境里边  ,访问 单个店铺时候会报错, 访问文件路径: http://www.test.com/supplier.php?suppId=5 类似这样的报错: D ...

  9. java框架---->Xstream的使用(一)

    Xstream可以轻易的将Java对象和xml文档相互转换,而且可以修改某个特定的属性和节点名称.今天我们就简单的学习一下xstream的用法. Xstream的简单实例 项目的结构如下,设计到三个类 ...

  10. 微信小程序5.2.2版本,找不着resource下exml皮肤

    问题描述: egret engine 5.2.2 原来5.1.11好好的,一升级就跪了 新建一个项目,找不到皮肤... 已发到论坛问去了,现在只能手动复制皮肤到小游戏目录下... 解决方案: 卸载重新 ...