A.每个状态只有一种后续转移,判断每次转移是否都合法即可。

  1. #include <iostream>
  2. #include <cstdio>
  3. using namespace std;
  4. int a[], n;
  5. bool check(int x){
  6. if(a[] == x) return false;
  7. int l = a[], r = x, s = -a[]-x;
  8. for(int i = ; i <= n; i++){
  9. if(a[i] == s) return false;
  10. l = a[i]; r = s; s = -l-r;
  11. }
  12. return true;
  13. }
  14.  
  15. int main()
  16. {
  17. cin>>n;
  18. for(int i = ; i <= n; i++) cin>>a[i];
  19. int f = ;
  20. if(check()) f = ;
  21. if(f == ) printf("YES");
  22. else printf("NO");
  23. return ;
  24. }

B.按照题意枚举约数判断即可。

  1. #include <iostream>
  2. using namespace std;
  3. int n;
  4. bool check(int x){
  5. for(int i = ; i <= ; i++){
  6. if( ((<<i) - )*(<<(i-)) == x) return true;
  7. if( ((<<i) - )*(<<(i-)) > x) return false;
  8. }
  9. }
  10. int a[];
  11. int main()
  12. {
  13. int ans = , temp = , last = , L;
  14. cin>>n;
  15. for(int i = ; i <= n; i++){
  16. if(n%i == )
  17. if(check(i))
  18. ans = max(ans, i);
  19. }
  20. cout<<ans<<endl;
  21. }

C.先用并查集并起来,然后瞎搞即可。

  1. #include <iostream>
  2. #include <cstdio>
  3. using namespace std;
  4. const int maxn = 1e5 + ;
  5. int a[maxn], f[maxn], v[maxn], s[maxn], M[maxn], x, y;
  6. int find(int x) { return x == f[x] ? f[x] : f[x] = find(f[x]); }
  7. int main()
  8. {
  9. long long ans = ;
  10. int n, m;
  11. cin>>n>>m;
  12. for(int i = ; i <= n; i++){
  13. scanf("%d", &a[i]);
  14. f[i] = i;
  15. v[i] = a[i];
  16. }
  17. for(int i = ; i <= m; i++){
  18. scanf("%d %d", &x, &y);
  19. f[find(x)] = find(y);
  20. }
  21. for(int i = ; i <= n; i++){
  22. v[find(i)] = min(v[find(i)], v[i]);
  23. }
  24. for(int i = ; i <= n; i++){
  25. if(M[find(i)] == ){
  26. M[find(i)] = ;
  27. ans += (long long)v[find(i)];
  28. }
  29. }
  30. cout<<ans<<endl;
  31. }

D.一道题意非常困难的题目orz。

题意大概就是:给你每天的金钱变化,你可以选择加任意数量的钱,但是需要保证每个时刻的钱数不超过d,而且当金钱变化为0时,此时钱的数量必须非负(check一次)

最后还是读错题了。

这道题贪心是对的,先考虑画出价格的折线图。

在第i天加钱,就相当于抬高i天以后的折线。

贪心地想,反正加更多的钱总是更优

所以如果在第i天加钱,就尽量多的加钱

而能加的钱数就是上限d - Max[i](Max为从i到n的后缀),如果比这个还多,那么后面必定会超

所以就在每个需要加钱的位置都贪心地加钱即可。

  1. #include <iostream>
  2. #include <cstdio>
  3. using namespace std;
  4. const int maxn = 1e5 + ;
  5. int a[maxn], n;
  6. long long b[maxn], Max[maxn], d;
  7. int main()
  8. {
  9. cin>>n>>d;
  10. for(int i = ; i <= n; i++) scanf("%d", &a[i]);
  11. b[] = ;
  12. for(int i = ; i <= n; i++) b[i] = b[i-] + a[i];
  13. Max[n] = b[n];
  14. for(int i = n-; i >= ; i--) Max[i] = max(b[i], Max[i+]);
  15. int t = , f = ;
  16. if(Max[] > d){
  17. f = ;
  18. } else {
  19. long long h = ;
  20. for(int i = ; i <= n; i++){
  21. if(a[i] == && b[i] + h < ){
  22. h = d - Max[i];
  23. t++;
  24. if(b[i] + h < ) { f = ; break; }
  25. }
  26. }
  27. }
  28. if(f){
  29. printf("-1");
  30. } else printf("%d", t);
  31. return ;
  32. }

E.给你一个数x,你需要把它拆成y个数的乘积,只要对应位置的yi有一个不同,方案就是不同的,问有多少种方案(负数也算)

首先考虑只有正数。

把x质因数拆分,然后对于每个质因数

你需要把它分配个y个数,比如24 = 3*2^3

其中就需要把3个2分配给y个数,实际上就是y个不同的盒子,3个球,问有多少种方案

答案就是C(y+3-1, y-1)

然后每个质因数乘起来就可以了。

如果是负数,那么其实就是每个正数的方案选出2个变成负数

就是C(n, 0) + C(n, 2) + ....  = 2^(n-1)

最后都乘起来就可以了。

这题很蠢的是数组越界了,因为n+m大于1e6,但是没有预处理到(以及找质因数的写法一定要注意)

  1. #include <iostream>
  2. #include <vector>
  3. #include <cstdio>
  4. #define mp make_pair
  5. #define fi first
  6. #define se second
  7. using namespace std;
  8. vector< pair<int, int> > V;
  9. const int MOD = 1e9 + ;
  10. typedef long long LL;
  11. LL f[], invf[];
  12. LL mypow(LL a, LL b){
  13. LL ans = ; for(; b; b >>= , (a *= a) %= MOD) if(b&) (ans *= a) %= MOD; return ans;
  14. }
  15. LL C(LL n, LL m){
  16. return f[n]*invf[m]%MOD*invf[n-m]%MOD;
  17. }
  18. int T, x, y;
  19. int main()
  20. {
  21. cin>>T;
  22. f[] = ;
  23. for(int i = ; i <= ; i++) f[i] = f[i-]*i%MOD;
  24. invf[] = mypow(f[], MOD-);
  25. for(int i = -; i >= ; i--) invf[i] = (invf[i+]*(i+))%MOD;
  26. while(T--){
  27. scanf("%d %d", &x, &y);
  28. int t = x;
  29. long long ans = ;
  30. for(int i = ; i*i <= x; i++){
  31. if(t % i == ){
  32. int temp = ;
  33. while(t % i == ) temp++, t /= i;
  34. (ans *= C(temp+y-, y-) ) %= MOD;
  35. }
  36. }
  37. if(t != ) (ans *= y) %= MOD;
  38. (ans *= mypow(, y-)) %= MOD;
  39. printf("%I64d\n", ans);
  40. }
  41. return ;
  42. }

F.给定一棵树,每次询问x构成的子树内,距离x结点小于等于k的点中值最小的是多少。强制在线

这题我是用可持久化线段树+维护dfs序做的,复杂度是nlogn。不过也有很暴力的线段树维护dfs序nlognlogn做法

具体思想就是可持久化线段树的结点对应是dfs序

插入的时间是按深度排序。

那么询问x,k

就是问插入时间从1~deep[x]+k所构成的树中,x的子树中结点最小的值是多少。

然后维护dfs序,就是查询tree(deep[x] + k, ein[x], eout[x])这个区间的值。

大概就是这样,没什么很坑的地方。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <vector>
  5. using namespace std;
  6. const int maxn = 2e5 + ;
  7. struct Node{
  8. Node *l, *r;
  9. int v;
  10. void maintain(){
  11. v = min(l->v, r->v);
  12. }
  13. }pool[maxn*], *root[maxn], *null;
  14. int pooltot = ;
  15. Node *newnode(){
  16. Node* temp = &pool[pooltot++];
  17. temp->l = temp->r = null; temp->v = 1e9; //
  18. return temp;
  19. }
  20. void init(){
  21. null = new Node();
  22. null->l = null->r = null;
  23. null->v = 1e9; //
  24. }
  25. void Insert(Node *&o, Node *o2, int l, int r, int k, int v){
  26. if(o == null) o = newnode();
  27. if(l == r) { o->v = min(v, o2->v); return; } //
  28. int mid = (l+r)/;
  29. if(k <= mid) {
  30. Insert(o->l, o2->l, l, mid, k, v);
  31. o->r = o2->r;
  32. } else {
  33. Insert(o->r, o2->r, mid+, r, k, v);
  34. o->l = o2->l;
  35. }
  36. o->maintain();
  37. }
  38. int Query(Node *o, int l, int r, int L, int R){
  39. if(o == null) return 1e9; //
  40. if(L <= l && r <= R) return o->v;
  41. int mid = (l+r)/, ans = 1e9; //
  42. if(L <= mid) ans = min(ans, Query(o->l, l, mid, L, R)); //
  43. if(R > mid) ans = min(ans, Query(o->r, mid+, r, L, R)); //
  44. return ans;
  45. }
  46. int tot = , Maxd, timer = ;
  47. int ein[maxn], deep[maxn], eout[maxn], a[maxn], lastd[maxn];
  48. vector<int> D[maxn], G[maxn];
  49. void dfs(int x, int fa, int d){
  50. ein[x] = ++tot;
  51. deep[x] = d;
  52. Maxd = max(d, Maxd);
  53. D[d].push_back(x);
  54. for(auto to : G[x]){
  55. if(to == fa) continue;
  56. dfs(to, x, d+);
  57. }
  58. eout[x] = tot;
  59. }
  60. int n, r, x, y, q;
  61. int main(){
  62. init();
  63. cin>>n>>r;
  64. for(int i = ; i <= n; i++) scanf("%d", &a[i]);
  65. for(int i = ; i < n; i++){
  66. scanf("%d %d", &x, &y);
  67. G[x].push_back(y);
  68. G[y].push_back(x);
  69. }
  70. dfs(r, r, );
  71. for(int i = ; i <= n + ; i++) root[i] = newnode();
  72. for(int i = ; i <= Maxd; i++){
  73. for(auto x : D[i]){
  74. Insert(root[timer+], root[timer], , tot, ein[x], a[x]);
  75. timer++;
  76. }
  77. lastd[i] = timer;
  78. }
  79. scanf("%d", &q);
  80. int last = ;
  81. while(q--){
  82. scanf("%d %d", &x, &y);
  83. x = (x+last)%n + ;
  84. y = (y+last)%n;
  85. printf("%d\n", last = Query(root[lastd[min(Maxd, deep[x]+y)]], , tot, ein[x], eout[x]));
  86. }
  87. }

Educational Codeforces Round 33 (Rated for Div. 2) 题解的更多相关文章

  1. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  2. Educational Codeforces Round 65 (Rated for Div. 2)题解

    Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...

  3. Educational Codeforces Round 64 (Rated for Div. 2)题解

    Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...

  4. Educational Codeforces Round 60 (Rated for Div. 2) 题解

    Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...

  5. Educational Codeforces Round 58 (Rated for Div. 2) 题解

    Educational Codeforces Round 58 (Rated for Div. 2)  题目总链接:https://codeforces.com/contest/1101 A. Min ...

  6. Educational Codeforces Round 33 (Rated for Div. 2) E. Counting Arrays

    题目链接 题意:给你两个数x,yx,yx,y,让你构造一些长为yyy的数列,让这个数列的累乘为xxx,输出方案数. 思路:考虑对xxx进行质因数分解,设某个质因子PiP_iPi​的的幂为kkk,则这个 ...

  7. Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query(主席树合并)

    题意 给定一棵 \(n\) 个点的带点权树,以 \(1\) 为根, \(m\) 次询问,每次询问给出两个值 \(p, k\) ,求以下值: \(p\) 的子树中距离 \(p \le k\) 的所有点权 ...

  8. Educational Codeforces Round 33 (Rated for Div. 2)A-F

    总的来说这套题还是很不错的,让我对主席树有了更深的了解 A:水题,模拟即可 #include<bits/stdc++.h> #define fi first #define se seco ...

  9. Educational Codeforces Round 33 (Rated for Div. 2) D. Credit Card

    D. Credit Card time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

随机推荐

  1. 【洛谷P4178】Tree

    题面 题解 感觉和\(CDQ\)分治一样套路啊 首先,构建出点分树 对于每一层分治重心,求出它到子树中任意点的距离 然后\(two-pointers\)计算满足小于等于\(K\)的点对数目,加入答案 ...

  2. 【LG2257】YY的GCD

    [LG2257]YY的GCD 题面 洛谷 题解 题目大意: 给定\(n,m\)求\(\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)为质数]\). 我们设\(f(x)=[x为 ...

  3. idea里绝对不要直接复制文件到项目中的另一处

    否则那样会将使用被复制文件的那些地方 文件名会变成复制后的那个 而路径是原来的 所以会导致找不到文件 所以绝对不要直接复制文件或者包或者目录到项目中的另一处 需要时应该新建文件 把代码复制进去 这种事 ...

  4. SQL优化避免索引失效

    Oracle 索引的目标是避免全表扫描,提高查询效率,但有些时候却适得其反.例如一张表中有上百万条数据,对某个字段加了索引,但是查询时性能并没有什么提高,这可 能是 oracle 索引失效造成的.or ...

  5. 在CentOS 7下编译安装Nginx+PHP+MySQL环境

    本文转载自:http://www.softeng.cn/?p=156,本文已获得作者授权,未经作者同意,不可转载. 1.前言 本文适合于已经对Linux操作系统具有基本操作经验,并且能够在Linux或 ...

  6. 进阶篇:4.1)DFA设计指南:简化产品设计(kiss原则)

    本章目的:理解kiss原则,明确如何简化产品的设计. 1.前言:kiss原则,优化产品的第一原则 如果要作者选出一个优化产品的最好方法,那一定是kiss原则莫属.从产品的整体设计到公差的分析,kiss ...

  7. Keil出错解决方法

    1.安装KEIL5后创建工程后出现这个报错 解决方法:打开下图目录的文件. Keil.STM32F1xx_DFP.pdsc文件是只读文件,必须将只读属性取消. 如下图所示,注释掉红色圆圈的哪一行,保存 ...

  8. Python接口测试实战2 - 使用Python发送请求

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  9. SQL数据类型(SQL Server六个类型使用)

    SQL数据类型是一个属性,它指定任何对象的数据的类型.在SQL中每一列,变量和表达有相关数据类型. 当创建表时,需要使用这些数据类型. 会选择根据表列要求选择一个特定的数据类型. SQL Server ...

  10. leetcode个人题解——#34 Find First and Last Position of Element in Sorted Array

    思路:先二分查找到一个和target相同的元素,然后再左边二分查找左边界,右边二分查找有边界. class Solution { public: , end = -; int ends; int lS ...