Problem A

题目大意

给定两个字符串,要求构造出一个最长的一个串满足:这个串是其中一个串的字序列并且不是另一个串的子序列.输出长度.\((len \leq 10^5)\)

题解

千万年死在读题上

我做题的时候:哇!这不是一道SB题嘛?

2mins敲完,提交Wrong answer

我去,好像看错题了。。我说怎么这道题这么二。。。

我重新看了眼题。。

那这题不更SB了吗??????

一边怀疑自己一边提交了上去,结果Accepted了。。

我去,判个字符串是否相等,再输出长度最大值就可以了

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long ll;
  6. inline void read(int &x){
  7. x=0;char ch;bool flag = false;
  8. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  9. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  10. }
  11. const int maxn = 100010;
  12. char s1[maxn],s2[maxn];
  13. int main(){
  14. scanf("%s%s",s1+1,s2+1);
  15. int len1 = strlen(s1+1);
  16. int len2 = strlen(s2+1);
  17. if(!strcmp(s1+1,s2+1)) puts("-1");
  18. else printf("%d\n",max(len1,len2));
  19. getchar();getchar();
  20. return 0;
  21. }

Problem B

题目大意

给定一个长为n的序列,判断是否能从这个序列中选出三个数使得这三个数可以组成一个三角形的三边长。\((n \leq 10^5)\)

题解

暴力枚举肯定不可行。

所以我们要有智商地枚举。

我们发现我们其实就是要在这里面选出三个数\(a,b,c\)满足

\(a+b > c ; a+c > b ; b+c > a\)

我们设\(a,b,c\)中最大值为\(a\),那么我们就发现\(a+b < c,a+c < b\)都一定成立

所以我们再选出两个小于等于\(a\)值满足\(b+c < a\)即可

所以我们直接对输入序列排序,顺序考虑\(a\)的取值

取第一个\(\leq a\)和第二个\(\leq a\)的值作为\(b,c\)判定即可

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long ll;
  6. inline void read(int &x){
  7. x=0;char ch;bool flag = false;
  8. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  9. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  10. }
  11. const int maxn = 100010;
  12. int a[maxn];
  13. int main(){
  14. int n;read(n);
  15. for(int i=1;i<=n;++i) read(a[i]);
  16. sort(a+1,a+n+1);
  17. bool flag = false;
  18. for(int i=3;i<=n;++i){
  19. if(a[i-2] + a[i-1] > a[i]){
  20. flag = true;
  21. break;
  22. }
  23. }
  24. puts(flag ? "YES" : "NO");
  25. getchar();getchar();
  26. return 0;
  27. }

Problem C

题目大意

分别规定\(26\)个字母中每个字母所在的字符串长度不能超过某一值,给定一个长为\(n\)的字符串,将其划分成一些子串,使这个字符串满足上述要求。求:方案数\((mod \text{ } 10^9 + 7)\)、可行划分方案中的最长字串长度、最少划分成多少字串。\((ln \leq 10^5)\)

题解

又是一道字符串。。。

我们看到求方案数+取模就知道这一般不是一道数论题就是一道dp题

我们又看到了这数据范围就可以确定这是一个dp了

我们设\(f[i]\)表示成功划分了\(1~i\)的字符串的方案数,然后我们枚举\(j \in [0,i-1]\)转移即可。

第二问、第三问可以在算方案数的过程中直接记录或用类似过程计算

//没取模挂掉一次

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long ll;
  6. inline void read(int &x){
  7. x=0;char ch;bool flag = false;
  8. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  9. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  10. }
  11. const int maxn = 1024;
  12. const int mod = 1000000007;
  13. int f[maxn],w[31],g[maxn];
  14. char s[maxn];
  15. inline int id(char ch){return ch - 'a' + 1;}
  16. int main(){
  17. memset(g,0x3f,sizeof g);
  18. int n;read(n);
  19. scanf("%s",s+1);
  20. for(int i=1;i<=26;++i) read(w[i]);
  21. f[0] = 1;g[0] = 0;
  22. int ans = 1;
  23. for(int i=1;i<=n;++i){
  24. int lim = w[id(s[i]) ];
  25. int cnt = 1,j=i-1;
  26. while(cnt <= lim && j >= 0){
  27. f[i] += f[j];if(f[i] >= mod) f[i] -= mod;
  28. g[i] = min(g[i],g[j] + 1);
  29. ans = max(ans,cnt);
  30. ++cnt;
  31. lim = min(lim,w[id(s[j--])]);
  32. }
  33. }printf("%d\n%d\n%d\n",f[n],ans,g[n]);
  34. getchar();getchar();
  35. return 0;
  36. }

Problem D

题目大意

给定n个词的含义相同或相反的共m个关系,关系具有传递性.每次给定关系的时候先判断此关系是否可以由前面的关系判断,如果不可以则添加此关系,否则判断此关系是否与推断出来的相符。最后询问q组词之间的关系。\((n,m,q \leq 10^5)\)

题解

一看这套路就知道是带权并查集。

每个节点维护父系指针和与父亲的关系。

我们把相反记为1,相同记为0.

每次判断亮点关系时只需要判断一下两点父亲是否相同

若父亲相同则可以推断两点的官司

若两点与父亲的关系均相同或均相反,则两点的关系为相同,否则为相反

至于关系的传递性嘛。。我们发现这个关系的传递性恰好是\(xor\)也就是异或

即\(num_{a->c} = num_{a->b}\text{ } xor \text{ }num_{b->c}\),其中\(num_{a->b}\)表示\(a,b\)的关系.

所以我们可以简单地完成路径压缩和查询。

竟然卡我的\(map!!!\)手写了颗\(Trie\)才过的...

  1. #include <map>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. inline void read(int &x){
  8. x=0;char ch;bool flag = false;
  9. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  10. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  11. }
  12. const int maxn = 100010;
  13. int fa[maxn],num[maxn];
  14. inline int find(int x){
  15. int f = x;while(f != fa[f]) f = fa[f];
  16. int y = fa[x],z;
  17. while(y != f){
  18. z = fa[x];
  19. while(z != f){
  20. num[x] ^= num[z];
  21. z = fa[z];
  22. }fa[x] = f;
  23. x = y;y = fa[x];
  24. }return f;
  25. }
  26. const int maxnode = maxn*22 + 10;
  27. int ch[maxnode][27],idx[maxnode],nodecnt;
  28. inline void insert(int x){
  29. char c;while(c = getchar(),c<'!');
  30. int nw = 0;
  31. while(c >= 'a' && c <= 'z'){
  32. if(ch[nw][c - 'a'] == 0) ch[nw][c - 'a'] = ++nodecnt;
  33. nw = ch[nw][c - 'a'];
  34. c = getchar();
  35. }idx[nw] = x;
  36. }
  37. inline int query(){
  38. char c;while(c = getchar(),c<'!');
  39. int nw = 0;
  40. while(c >= 'a' && c <= 'z'){
  41. nw = ch[nw][c - 'a'];
  42. c = getchar();
  43. }return idx[nw];
  44. }
  45. int main(){
  46. int n,m,q;read(n);read(m);read(q);
  47. for(int i=1;i<=n;++i){
  48. insert(i);
  49. fa[i] = i;
  50. }
  51. for(int i=1,c;i<=m;++i){
  52. read(c);--c;
  53. int x = query();
  54. int y = query();
  55. //printf("linking %d %d\n",x,y);
  56. int fx = find(x);
  57. int fy = find(y);
  58. if(fx == fy){
  59. if( (c == 0) == (num[x] == num[y]) ) puts("YES");
  60. if( (c == 0) != (num[x] == num[y]) ) puts("NO");
  61. }else{
  62. fa[fx] = fy;
  63. if(num[x]^num[y] == c) num[fx] = 0;
  64. else num[fx] = 1;
  65. puts("YES");
  66. }
  67. }
  68. while(q--){
  69. int x = query();
  70. int y = query();
  71. int fx = find(x);
  72. int fy = find(y);
  73. if(fx != fy) puts("3");
  74. else printf("%d\n",(num[x] != num[y]) + 1);
  75. }
  76. getchar();getchar();
  77. return 0;
  78. }

Problen E

题目大意

给定一颗点有点权\((val_i \leq 10^6)\)的n个节点的树,定义两点距离为路径上点权异或和。求所有无序点对之间的距离之和。\((n \leq 10^5)\)

题解

因为这道题是对二进制数位进行操作

常规方法不好做的时候应该自然而然地想到对每个数位分别讨论。

我们发现:把每个数位拆开之后,所有的点权都变成了0/1

然后我们要统计的就是xor后为1的数对的个数

我们考虑树形dp

设\(f[i][j]\)表示以i为根的子树中到达点i时xor后得到j的节点数目.

即j是0或1

然后我们\(O(n)\)一遍可以算出所有点向上的贡献.

我们再\(dfs\)一遍算出所有点向下的贡献即可.

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long ll;
  6. inline void read(int &x){
  7. x=0;char ch;bool flag = false;
  8. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  9. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  10. }
  11. const int maxn = 100010;
  12. bool w[maxn];
  13. int a[maxn],f[maxn][2];
  14. struct Edge{
  15. int to,next;
  16. }G[maxn<<1];
  17. int head[maxn],cnt;
  18. void add(int u,int v){
  19. G[++cnt].to = v;
  20. G[cnt].next = head[u];
  21. head[u] = cnt;
  22. }
  23. inline void insert(int u,int v){
  24. add(u,v);add(v,u);
  25. }
  26. #define v G[i].to
  27. void dfs(int u,int fa){
  28. f[u][0] = f[u][1] = 0;f[u][w[u]] = 1;
  29. for(int i = head[u];i;i=G[i].next){
  30. if(v == fa) continue;
  31. dfs(v,u);
  32. f[u][w[u]^0] += f[v][0];
  33. f[u][w[u]^1] += f[v][1];
  34. }return;
  35. }ll num;
  36. void dfs(int u,int fa,int zero,int one){
  37. f[u][w[u]^0] += zero;f[u][w[u]^1] += one;
  38. num += f[u][1];
  39. int g[2];
  40. for(int i=head[u];i;i=G[i].next){
  41. if(v == fa) continue;
  42. g[w[u]^1] = f[u][w[u]^1] - f[v][1];
  43. g[w[u]^0] = f[u][w[u]^0] - f[v][0];
  44. dfs(v,u,g[0],g[1]);
  45. }
  46. }
  47. #undef v
  48. int main(){
  49. int n;read(n);
  50. for(int i=1;i<=n;++i) read(a[i]);
  51. for(int i=1,u,v;i<n;++i){
  52. read(u);read(v);
  53. insert(u,v);
  54. }
  55. #define v G[i].to
  56. ll ans = 0;
  57. for(int bit=1;bit<=30;++bit){
  58. num = 0;
  59. ll x = 0;
  60. for(int i=1;i<=n;++i){
  61. w[i] = (a[i] >> (bit-1)) & 1;
  62. if(w[i] == 1) ++ x;
  63. }
  64. dfs(1,0);
  65. dfs(1,0,0,0);
  66. num = ((num-x)>>1) + x;
  67. ans += num<<bit-1;
  68. }
  69. #undef v
  70. printf("%lld\n",ans);
  71. getchar();getchar();
  72. return 0;
  73. }

在vjudge上做完这些题后去codeforces开了Virtual participation,4分钟AC五道题,真爽!

Codeforces round 396(Div. 2) 题解的更多相关文章

  1. Codeforces Round #182 (Div. 1)题解【ABCD】

    Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...

  2. Codeforces Round #608 (Div. 2) 题解

    目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...

  3. Codeforces Round #525 (Div. 2)题解

    Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...

  4. Codeforces Round #528 (Div. 2)题解

    Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...

  5. Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F

    Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...

  6. Codeforces Round #677 (Div. 3) 题解

    Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...

  7. Codeforces Round #665 (Div. 2) 题解

    Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...

  8. Codeforces Round #160 (Div. 1) 题解【ABCD】

    Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...

  9. Codeforces Round #383 (Div. 2) 题解【ABCDE】

    Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...

随机推荐

  1. 强大易用的日期和时间库 Joda Time

    Joda-Time提供了一组Java类包用于处理包括ISO8601标准在内的date和time.可以利用它把JDK Date和Calendar类完全替换掉,而且仍然能够提供很好的集成,并且它是线程安全 ...

  2. 使用chrome调试前端线上代码

    家都知道在前端开发过程中,为加快网站静态资源加载速度都会对js/css等静态资源进行压缩合并再部署到生产环境,而在实际开发过程中开发人员一般都是在开发环境进行源码文件开发调试的,当部署平台或部署人员将 ...

  3. 利用xlrd模块实现Python读取Excel文档

    # -*- coding: cp936 -*- #python读取excel import xlrd def main(): xls=xlrd.open_workbook("d:\\11.x ...

  4. VMware 中安装Centos

    1,在百度软件中心下载VM12 http://rj.baidu.com/soft/detail/13808.html?ald 2,一路NEXT安装,安装完之后需要秘钥激活. VMware Workst ...

  5. 16 redis之sentinel运维监控

    一:sentinel运维监控 Sentinel不断与master通信,获取master的slave信息. 监听master与slave的状态 如果某slave失效,直接通知master去除该slave ...

  6. kfaka windows安装

    1 官网下载 解压到D:\developTools\kfaka\kafka_2.10-0.9.0.0 2 windows cmd启动 新开cmd命令:cd /d D:\developTools\kfa ...

  7. wpf自定义colorpicker

    自定义colorpicker <ObjectDataProvider MethodName="GetType" ObjectType="{x:Type system ...

  8. node / npm/ yarn 的安装以及环境变量

    # node.js 10.15.3 https://npm.taobao.org/mirrors/node/v10.15.3/node-v10.15.3-x64.msi 1.安装后自动添加了环境变量: ...

  9. 【BZOJ1018】[SHOI2008]堵塞的交通traffic 线段树

    [BZOJ1018][SHOI2008]堵塞的交通traffic Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个 ...

  10. java array

    1 array变量 Type[] array_virable_name; 2 array对象 2.1 new Type[] array_virable_name = new Type[NUM]; 2. ...