Problem A:QAQ

给一个字符串,求出可非连续的QAQ序列有多少个。

Analysis:比较水的一道题,记录每一个Q的位置,预处理A的个数即可

然而还是fst了,原因是未考虑一个Q都没有的极端情况,导致vector().size-1溢出!

以后一定要注意,当对unsigned int类型的vector().size作减法时考虑是否可能出现负数情况

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. int cnt[];
  5. string s;
  6. vector<int> q;
  7.  
  8. int main()
  9. {
  10. cin >> s;
  11. for(int i=;i<s.size();i++)
  12. {
  13. cnt[i+]=cnt[i];
  14. if(s[i]=='A') cnt[i+]++;
  15. else if(s[i]=='Q') q.push_back(i+);
  16. }
  17.  
  18. if(!q.size()) cout << ,return ; //对极端情况要特殊考虑
  19. //因为vector.size()是unsigned int,减1时会溢出
  20. int res=;
  21. for(int i=;i<q.size()-;i++)
  22. for(int j=i+;j<q.size();j++)
  23. {
  24. int x=q[i],y=q[j];
  25. res+=(cnt[y]-cnt[x]);
  26. }
  27. cout << res;
  28.  
  29. return ;
  30. }

Problem A

Problem B:Ralph and his magic field

喜闻乐见的组合数学题,可划归为:在一个n*m的表格上填0和1,问在每行每列的和均为奇数或偶数时总方案数为多少

Analysis:一道比较考思维的题目,而思维能力不足一直我的弱项

其实看到n,m为1e18就知道是结论题,这时候推不出来暴力打表找规律也行啊,以后还是要灵活一些

正解就是把问题转换成(n-1)*(m-1)的全排列问题,最后的一行一列根据最终要求推出来就行了

但要注意的是,当要求为奇数,且n、m奇偶性不同时,方案数为0

            (证明:1、反证法:只看横行为偶数个奇数,只看竖行为奇数个奇数,但总和不应有变,矛盾

                          2、利用(n-1)*(m-1)的矩形来证明:在(n-1)*(m-1)表上均为1时,最后一行和最后一列奇偶性必然不同,而每将1个1变为0,两边的奇偶性都不会变为相同)

             

           至于求2^(n-1)^(m-1)就没什么好讲的了,只要注意快速幂必须分两次求,否则(n-1)*(m-1)会爆long long

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. const int MOD=;
  5.  
  6. long long n,m;
  7. int k;
  8.  
  9. long long quick_pow(long long a,long long b)
  10. {
  11. long long base=a,res=;
  12. while(b)
  13. {
  14. if(b%) res=res*base%MOD;
  15. b>>=;
  16. base=base*base%MOD;
  17. }
  18.  
  19. return res;
  20. }
  21.  
  22. int main()
  23. {
  24. cin >> n >> m >> k;
  25.  
  26. if(k==- && (n%!=m%)) cout << ;
  27. else cout << quick_pow(quick_pow(,n-),m-);
  28.  
  29. return ;
  30. }

Problem B

Problem C:Marco and GCD Sequence

这次中国选手出题就变成数学大赛了啊(雾

给定有序集合S,S是由一个n个元素组成的序列中对于每个1 ≤ i ≤ j ≤ n计算出的gcd(ai, ai + 1, ..., aj)产生的,输出你构造的序列,如没有输出-1

Analysis:又是一道思维题

我当时的想法是既然序列中的数肯定都属于S,且S中的最后一个数必选,那从后往前贪心选取不就行了。当时写起来便很虚,其实明显是有bug的,因为没有想到普遍构造

对于这类构造题,首先可以想一想如果将条件变强,是否存在一种通解

对于本题而言,便猜想如果s1,s2,s3.......sn均为s1,即gcd(a1,a2....an)的倍数时,便可将序列构造为s1,s2,s1,s3,s1,s4,s1,s5.....s1,sn

那如果s1不是s1,s2,s3....sn的公约数呢?那便可证明不存在这样的序列,因为a1,a2....an的最大公约数便是s1。

              对于此题,我只想到S中的最后一个数必然为an,却未想到S1必然是a1,a2,a3.....an的最大公约数

对这类序列区间求值后统一排序的题目首尾均是关键

              其次,在发现线性算法无法很好解决时,考虑对特定情况下的构造,再进行推广

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. int m,dat[];
  5.  
  6. int gcd(int a,int b)
  7. {
  8. if(a%b==) return b;
  9. else return gcd(b,a%b);
  10. }
  11.  
  12. int main()
  13. {
  14. cin >> m;
  15. for(int i=;i<=m;i++) cin >> dat[i];
  16.  
  17. if(m==)
  18. {
  19. cout << << endl << dat[];
  20. return ;
  21. }
  22.  
  23. int all=dat[];
  24. for(int i=;i<=m;i++) all=gcd(all,dat[i]);
  25.  
  26. if(all!=dat[]) cout << -;
  27. else
  28. {
  29. cout << *(m-) << endl;
  30. for(int i=;i<=m;i++) cout << dat[] << " " << dat[i] << " ";
  31. }
  32.  
  33. return ;
  34. }

Problem C

Problem D:Ralph And His Tour in Binary Country

给定一棵树,每次给1个点A,求到A的距离不超过H的点到A的距离和

Analysis:这道题一开始以为要树剖,结果发现并不用

在每一颗子树下,可以预处理出子树下所有点到子树根节点的距离及前缀和,从而O(logn)求出该子树下到子树根节点距离不超过H-x的和

因此,我们可以从A节点开始,一层层向上遍历,找父亲,直到距离已超过H,每次求出当前子树下到子树根节点B距离不超过H-x(A到B的距离)的和

但这样明显会有一定的重复计算,因此每次我们找到父亲后,只能查找该父亲下的另一棵子树

这时实现时有一些小技巧:1、当数据在节点时可以递归建树时。但当数据在边上时,应当以边为线索进行建树

                                                         2、树上的遍历为保证不重复,只要每次记录上一次操作的last节点,保证不重复计算

3、找到边与点的关系,在本题中,第i个点到其父节点的边为Ei-1

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. typedef long long ll;
  5. const int MAXN=;
  6.  
  7. int n,m,len[MAXN],A,H,t[MAXN];
  8. vector<int> a[MAXN];
  9. vector<ll> pre[MAXN];
  10.  
  11. inline int read() //OI优化标准模块,专防卡常
  12. {
  13. char ch;int num,f=;
  14. while(!isdigit(ch=getchar())) f|=(ch=='-');
  15. num=ch-'';
  16. while(isdigit(ch=getchar())) num=num*+ch-'';
  17. return f?-num:num;
  18. }
  19.  
  20. inline void write(ll x)
  21. {
  22. if(x<) putchar('-'),x=-x;
  23. if(x>) write(x/);
  24. putchar(x%+'');
  25. }
  26.  
  27. void merge(int x,int y) //类似于归并排序的操作
  28. {
  29. int lx=a[x].size(),ly=a[y].size(),d=len[y-];
  30. int k=,p=,q=;
  31.  
  32. while(p<lx && q<ly)
  33. {
  34. if(a[x][p]<a[y][q]+d) t[k++]=a[x][p],p++;
  35. else t[k++]=a[y][q]+d,q++;
  36. }
  37.  
  38. while(p<lx) t[k++]=a[x][p],p++;
  39. while(q<ly) t[k++]=a[y][q]+d,q++;
  40.  
  41. a[x].clear();
  42. for(int i=;i<k;i++) a[x].push_back(t[i]);
  43. }
  44.  
  45. ll cal(int node,ll tar)
  46. {
  47. ll ret=;
  48. ll pos=lower_bound(a[node].begin(),a[node].end(),tar)-a[node].begin()-;
  49. ret=tar*(pos+)-pre[node][pos];
  50.  
  51. return ret;
  52. }
  53.  
  54. ll BinaryCount(int node)
  55. {
  56. ll res=,t=H,last=node; //last保证不重复计算
  57. res+=cal(node,t);t-=len[node-];node>>=; //先加上当前节点
  58. while(node> && t>)
  59. {
  60. res+=t; //加上当前的根节点
  61. int lch=(node<<),rch=((node<<)|); //处理当前根节点下的子节点
  62. if(lch<=n && lch!=last && t-len[lch-]>) res+=cal(lch,t-len[lch-]);
  63. if(rch<=n && rch!=last && t-len[rch-]>) res+=cal(rch,t-len[rch-]);
  64.  
  65. last=node;t-=len[node-];node>>=;
  66. }
  67. return res;
  68. }
  69.  
  70. int main()
  71. {
  72. cin >> n >> m;
  73. for(int i=;i<=n-;i++) len[i]=read();
  74. for(int i=;i<=n;i++) a[i].push_back();
  75.  
  76. for(int i=n;i>;i--) merge(i/,i); //以边为线索进行更新
  77.  
  78. for(int i=;i<=n;i++) //对前缀和的预处理
  79. for(int j=;j<a[i].size();j++)
  80. if(!j) pre[i].push_back(a[i][j]);
  81. else pre[i].push_back(pre[i][j-]+a[i][j]);
  82.  
  83. for(int i=;i<=m;i++)
  84. {
  85. cin >> A >> H;
  86. write(BinaryCount(A));cout << endl;
  87. }
  88.  
  89. return ;
  90. }

Problem D

Problem E:Ralph and Mushrooms

Analysis:莫名其妙,E题成了道简单题

主要就是先Tarjan缩点,在每一个强联通分量里对数据进行特殊计算

接下来在DAG上求最长路

注意,此题的起点不一定入度为零,因此不能直接拓扑排序,应记忆化搜索

Tips:1、对(n-1)+(n-2)+(n-3)+(n-4)......(n-k)的计算是一个难点,标算的数学计算法还没看懂......

2、对于DAG的处理:不一定非要拓扑+DP,可以直接记忆化搜索,但要注意的是此时维护的是到终止节点的最大距离

                      3、Tarjan缩点后重新建图时,可以不用处理两个节点间的多条边

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. typedef pair<int,int> P;
  5.  
  6. const int N=;
  7. int n,m,st,low[N],dfn[N],time_point=,col[N],cnt=;
  8. bool vis[N],instack[N];
  9. long long res=,tot[N],dp[N];
  10.  
  11. inline int read()
  12. {
  13. char ch;
  14. while(!isdigit(ch=getchar()));
  15. int num=ch-'';
  16. while(isdigit(ch=getchar())) num=num*+ch-'';
  17. return num;
  18. }
  19.  
  20. struct ed
  21. {
  22. int x,y,w;
  23. }edge[N];
  24.  
  25. vector<P> a[N];
  26. stack<int> s;
  27.  
  28. void tarjan(int cur) //Tarjan模板
  29. {
  30. time_point++;
  31. dfn[cur]=low[cur]=time_point;
  32. vis[cur]=true;
  33. instack[cur]=true;
  34. s.push(cur);
  35.  
  36. for(int i=;i<a[cur].size();i++)
  37. {
  38. int u=a[cur][i].first;
  39. if(!vis[u])
  40. {
  41. tarjan(u);
  42. low[cur]=min(low[cur],low[u]);
  43. }
  44. else if(instack[u])
  45. {
  46. low[cur]=min(low[cur],low[u]);
  47. }
  48. }
  49.  
  50. if(dfn[cur]==low[cur])
  51. {
  52. cnt++;int t;
  53. do
  54. {
  55. t=s.top();s.pop();
  56. instack[t]=false;
  57. col[t]=cnt;
  58. }while(t!=cur);
  59. }
  60. }
  61.  
  62. long long cal(int t) //标算的数学计算法
  63. {
  64. long long k=(long long)(sqrtl((long double)t*+0.25)-0.5);
  65. return (k*(*t-(k+)*(k+)))/+t;
  66. }
  67.  
  68. void dfs(int node) //记忆化
  69. {
  70. if(dp[node]) return;
  71. for(int i=;i<a[node].size();i++)
  72. {
  73. int v=a[node][i].first;
  74. dfs(v);
  75. dp[node]=max(dp[node],dp[v]+a[node][i].second); //维护到终止点的值
  76. }
  77. dp[node]+=tot[node]; //在完结后才加上当前节点的值
  78. }
  79.  
  80. int main()
  81. {
  82. n=read();m=read();
  83. for(int i=;i<=m;i++)
  84. {
  85. edge[i].x=read();edge[i].y=read();edge[i].w=read();
  86. a[edge[i].x].push_back(P(edge[i].y,edge[i].w));
  87. }
  88. st=read();
  89.  
  90. tarjan(st);
  91.  
  92. for(int i=;i<N;i++) a[i].clear();
  93.  
  94. for(int i=;i<=m;i++) //对缩点后每一个点的数据更新
  95. {
  96. int u=edge[i].x,v=edge[i].y;
  97. if(col[u]==col[v])
  98. {
  99. tot[col[u]]+=cal(edge[i].w);
  100. }
  101. }
  102. for(int i=;i<=m;i++)
  103. {
  104. int u=edge[i].x,v=edge[i].y; //这里可以不用考虑两个点间有多条边的情况
  105. if(col[u]!=col[v])
  106. {
  107. a[col[u]].push_back(P(col[v],edge[i].w));
  108. }
  109. }
  110.  
  111. dfs(col[st]);
  112.  
  113. cout << dp[col[st]];
  114.  
  115. return ;
  116. }

Problem E

Codeforces #447 Div.2 Tutorial的更多相关文章

  1. Codeforces #344 Div.2

    Codeforces #344 Div.2 Interview 题目描述:求两个序列的子序列或操作的和的最大值 solution 签到题 时间复杂度:\(O(n^2)\) Print Check 题目 ...

  2. Codeforces #345 Div.1

    Codeforces #345 Div.1 打CF有助于提高做题的正确率. Watchmen 题目描述:求欧拉距离等于曼哈顿距离的点对个数. solution 签到题,其实就是求有多少对点在同一行或同 ...

  3. Codeforces Beta Round #27 (Codeforces format, Div. 2)

    Codeforces Beta Round #27 (Codeforces format, Div. 2) http://codeforces.com/contest/27 A #include< ...

  4. Codeforces#441 Div.2 四小题

    Codeforces#441 Div.2 四小题 链接 A. Trip For Meal 小熊维尼喜欢吃蜂蜜.他每天要在朋友家享用N次蜂蜜 , 朋友A到B家的距离是 a ,A到C家的距离是b ,B到C ...

  5. codeforces #592(Div.2)

    codeforces #592(Div.2) A Pens and Pencils Tomorrow is a difficult day for Polycarp: he has to attend ...

  6. codeforces #578(Div.2)

    codeforces #578(Div.2) A. Hotelier Amugae has a hotel consisting of 1010 rooms. The rooms are number ...

  7. codeforces #577(Div.2)

    codeforces #577(Div.2) A  Important Exam A class of students wrote a multiple-choice test. There are ...

  8. codeforces #332 div 2 D. Spongebob and Squares

    http://codeforces.com/contest/599/problem/D 题意:给出总的方格数x,问有多少种不同尺寸的矩形满足题意,输出方案数和长宽(3,5和5,3算两种) 思路:比赛的 ...

  9. Codeforces Round #447 (Div. 2) B. Ralph And His Magic Field 数学

    题目链接 题意:给你三个数n,m,k;让你构造出一个nm的矩阵,矩阵元素只有两个值(1,-1),且满足每行每列的乘积为k,问你多少个矩阵. 解法:首先,如果n,m奇偶不同,且k=-1时,必然无解: 设 ...

随机推荐

  1. Linux 中使用 dd 测试磁盘性能

    翻译自 : Linux I/O Performance Tests using dd 基本说明 dd 可以用来做简单的低级别复制文件. 这样做, 一般都是可一直直接访问设备文件. 需要说明的是, 错误 ...

  2. 聂老师的考验(反向bfs)

    题目链接:http://113.240.233.2:8081/JudgeOnline/problem.php?id=1121 这个题看起来要多次使用bfs,其实只要换个思维就会发现这就是一个简单的bf ...

  3. C# SuperSocket 消息推送

    服务端使用Nuget引用SuperSocket.WebSocket和SuperSocket.Engine 服务器端代码[控制台] using SuperSocket.WebSocket; using ...

  4. End to End Sequence Labeling via Bidirectional LSTM-CNNs-CRF论文小结

    本篇论文是卡内基梅隆大学语言技术研究所2016年  arXiv:1603.01354v5 [cs.LG] 29 May 2016 今天先理解一下这个是什么意思:        找到的相关理解:arXi ...

  5. Linux内核堆栈使用方法 进程0和进程1【转】

    转自:http://blog.csdn.net/yihaolovem/article/details/37119971 目录(?)[-] 8 Linux 系统中堆栈的使用方法 81  初始化阶段 82 ...

  6. Yii 1.1.17 二、Gii创建后台与后台登录验证

    一.用Gii创建后台模块 1.启用gii,在config/main.php 'gii' => array( 'class' => 'system.gii.GiiModule', 'pass ...

  7. WAMP Apache 2.5 配置虚拟主机

    1.在 Apache 的安装目录下 conf/httpd.conf 文件中搜索 hosts,去掉 Include 前面的 “#” 号后,即可启用虚拟主机. # Virtual hosts #Inclu ...

  8. 64_c1

    CBFlib-0.9.5.15-3.fc26.i686.rpm 05-Feb-2017 21:55 427710 CBFlib-0.9.5.15-3.fc26.x86_64.rpm 05-Feb-20 ...

  9. socket.io入门整理

    我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写了一个简单的聊天程序. 最最开始 先安装socket.io: 1 npm install socket.io 利用Nod ...

  10. 2017多校第8场 HDU 6143 Killer Names 容斥,组合计数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6143 题意:m种颜色需要为两段长度为n的格子染色,且这两段之间不能出现相同的颜色,问总共有多少种情况. ...