Problem A

题目大意

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

题解

千万年死在读题上
我做题的时候:哇!这不是一道SB题嘛?
2mins敲完,提交Wrong answer
我去,好像看错题了。。我说怎么这道题这么二。。。
我重新看了眼题。。
那这题不更SB了吗??????
一边怀疑自己一边提交了上去,结果Accepted了。。
我去,判个字符串是否相等,再输出长度最大值就可以了

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){x=0;char ch;bool flag = false;while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 100010;
char s1[maxn],s2[maxn];
int main(){scanf("%s%s",s1+1,s2+1);int len1 = strlen(s1+1);int len2 = strlen(s2+1);if(!strcmp(s1+1,s2+1)) puts("-1");else printf("%d\n",max(len1,len2));getchar();getchar();return 0;
}

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\)判定即可

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){x=0;char ch;bool flag = false;while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 100010;
int a[maxn];
int main(){int n;read(n);for(int i=1;i<=n;++i) read(a[i]);sort(a+1,a+n+1);bool flag = false;for(int i=3;i<=n;++i){if(a[i-2] + a[i-1] > a[i]){flag = true;break;}}puts(flag ? "YES" : "NO");getchar();getchar();return 0;
}

Problem C

题目大意

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

题解

又是一道字符串。。。
我们看到求方案数+取模就知道这一般不是一道数论题就是一道dp题
我们又看到了这数据范围就可以确定这是一个dp了
我们设\(f[i]\)表示成功划分了\(1~i\)的字符串的方案数,然后我们枚举\(j \in [0,i-1]\)转移即可。
第二问、第三问可以在算方案数的过程中直接记录或用类似过程计算
//没取模挂掉一次

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){x=0;char ch;bool flag = false;while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 1024;
const int mod = 1000000007;
int f[maxn],w[31],g[maxn];
char s[maxn];
inline int id(char ch){return ch - 'a' + 1;}
int main(){memset(g,0x3f,sizeof g);int n;read(n);scanf("%s",s+1);for(int i=1;i<=26;++i) read(w[i]);f[0] = 1;g[0] = 0;int ans = 1;for(int i=1;i<=n;++i){int lim = w[id(s[i]) ];int cnt = 1,j=i-1;while(cnt <= lim && j >= 0){f[i] += f[j];if(f[i] >= mod) f[i] -= mod;g[i] = min(g[i],g[j] + 1);ans = max(ans,cnt);++cnt;lim = min(lim,w[id(s[j--])]);}}printf("%d\n%d\n%d\n",f[n],ans,g[n]);getchar();getchar();return 0;
}

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\)才过的...

#include <map>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){x=0;char ch;bool flag = false;while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 100010;
int fa[maxn],num[maxn];
inline int find(int x){int f = x;while(f != fa[f]) f = fa[f];int y = fa[x],z;while(y != f){z = fa[x];while(z != f){num[x] ^= num[z];z = fa[z];}fa[x] = f;x = y;y = fa[x];}return f;
}
const int maxnode = maxn*22 + 10;
int ch[maxnode][27],idx[maxnode],nodecnt;
inline void insert(int x){char c;while(c = getchar(),c<'!');int nw = 0;while(c >= 'a' && c <= 'z'){if(ch[nw][c - 'a'] == 0) ch[nw][c - 'a'] = ++nodecnt;nw = ch[nw][c - 'a'];c = getchar();}idx[nw] = x;
}
inline int query(){char c;while(c = getchar(),c<'!');int nw = 0;while(c >= 'a' && c <= 'z'){nw = ch[nw][c - 'a'];c = getchar();}return idx[nw];
}
int main(){int n,m,q;read(n);read(m);read(q);for(int i=1;i<=n;++i){insert(i);fa[i] = i;}for(int i=1,c;i<=m;++i){read(c);--c;int x = query();int y = query();//printf("linking %d %d\n",x,y);int fx = find(x);int fy = find(y);if(fx == fy){if( (c == 0) == (num[x] == num[y]) ) puts("YES");if( (c == 0) != (num[x] == num[y]) ) puts("NO");}else{fa[fx] = fy;if(num[x]^num[y] == c) num[fx] = 0;else num[fx] = 1;puts("YES");}}while(q--){int x = query();int y = query();int fx = find(x);int fy = find(y);if(fx != fy) puts("3");else printf("%d\n",(num[x] != num[y]) + 1);}getchar();getchar();return 0;
}

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\)一遍算出所有点向下的贡献即可.

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){x=0;char ch;bool flag = false;while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 100010;
bool w[maxn];
int a[maxn],f[maxn][2];
struct Edge{int to,next;
}G[maxn<<1];
int head[maxn],cnt;
void add(int u,int v){G[++cnt].to = v;G[cnt].next = head[u];head[u] = cnt;
}
inline void insert(int u,int v){add(u,v);add(v,u);
}
#define v G[i].to
void dfs(int u,int fa){f[u][0] = f[u][1] = 0;f[u][w[u]] = 1;for(int i = head[u];i;i=G[i].next){if(v == fa) continue;dfs(v,u);f[u][w[u]^0] += f[v][0];f[u][w[u]^1] += f[v][1];}return;
}ll num;
void dfs(int u,int fa,int zero,int one){f[u][w[u]^0] += zero;f[u][w[u]^1] += one;num += f[u][1];int g[2];for(int i=head[u];i;i=G[i].next){if(v == fa) continue;g[w[u]^1] = f[u][w[u]^1] - f[v][1];g[w[u]^0] = f[u][w[u]^0] - f[v][0];dfs(v,u,g[0],g[1]);}
}
#undef v
int main(){int n;read(n);for(int i=1;i<=n;++i) read(a[i]);for(int i=1,u,v;i<n;++i){read(u);read(v);insert(u,v);}
#define v G[i].toll ans = 0;for(int bit=1;bit<=30;++bit){num = 0;ll x = 0;for(int i=1;i<=n;++i){w[i] = (a[i] >> (bit-1)) & 1;if(w[i] == 1) ++ x;}dfs(1,0);dfs(1,0,0,0);num = ((num-x)>>1) + x;ans += num<<bit-1;}
#undef vprintf("%lld\n",ans);getchar();getchar();return 0;
}

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

转载于:https://www.cnblogs.com/Skyminer/p/6395198.html

Codeforces round 396(Div. 2) 题解相关推荐

  1. Codeforces Round #514 (Div. 2)题解

    Codeforces Round #514 (Div. 2)题解 A 喵,直接模拟. B 枚举所有盖章时的,合法的,左上角的位置.能盖的话就盖一下.最后check一下图案是否相等即可 C 一轮一轮的扔 ...

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

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

  3. 【算法题解】Codeforces Round #817 (Div. 4)题解

    文章目录 Codeforces Round #817 (Div. 4)题解 A. Spell Check B. Colourblindness C. Word Game D. Line E. Coun ...

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

    Codeforces Round #747 (Div. 2)题解 (本博客将持续更新以后每场CF div2的题解,喜欢ACM.OI的小伙伴记得点个关注哟) 昨天夜晚刷网络流刷入迷了,渐渐就忘记了我还要 ...

  5. Codeforces Round #789 (Div. 2)题解

    Codeforces Round #789 (Div. 2)题解 A. Tokitsukaze and All Zero Sequence 原题链接 算法标签 贪心 排序 思路 情况一:数组存在零 → ...

  6. Codeforces Round #748 (Div. 3) 题解 完整A~G

    Codeforces Round #748 (Div. 3) 题解 A. Elections 题意 已知竞选中三个候选人的当前得票数 a , b , c a,b,c a,b,c,现在可以增加任何一个人 ...

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

    link orz olinr AK Codeforces Round #533 (Div. 2) 中文水平和英文水平都太渣..翻译不准确见谅 T1.给定n<=1000个整数,你需要钦定一个值t, ...

  8. Codeforces Round #734 (Div. 3) 题解

    Hello大家好,今天给大家带来的是 Codeforces Round #734 (Div. 3) 的全题目讲解. 本文链接:https://www.lanqiao.cn/questions/2040 ...

  9. Codeforces Round #462 (Div. 2)题解

    Codeforces Round #462 (Div. 2) B题--我固执的认为1e18是18位数,导致被hack,花了20分钟才检查出这个错误,很僵硬 Codeforces 934C 题意 给定一 ...

最新文章

  1. 谷歌大脑2017总结1
  2. selenium2与python自动化2-元素定位
  3. MySQL索引介绍,普通索引,全文索引,空间索引,多列索引使用原则,建立索引常用的规则
  4. linux下安装glibc-2.14,解决“`GLIBC_2.14' not found”问题
  5. centos安装nginx,配置负载均衡
  6. linux php c 扩展,linux php添加扩展库
  7. Oracle11 startup报错,oracle11g 启动报错 缺少系统参数
  8. CSS3-多列布局-伸缩盒布局-伸缩项目
  9. [论文阅读] Active Learning for Deep Object Detection via Probabilistic Modeling
  10. [note] Homebrew的介绍、安装方法与常用命令整理
  11. 51Nod1344走格子
  12. win10怎么修复网络连接服务器失败,微软发布修复补丁修复Win10无网络连接问题...
  13. CLion配置STM32(保姆级教程)
  14. postman替换快捷键ctrl加什么_你会用 Ctrl + ~ 键吗?
  15. DDNS请求到底请求了什么
  16. Spring Boot 微信-验证服务器有效性
  17. Elasticsearch7.12常用操作总结
  18. 什么是Shmoo图和Shmoo测试
  19. 芯片级封装LED(CSP+LED)行业调研报告 - 市场现状分析与发展前景预测
  20. mysql安装后没有mysql数据库怎么处理

热门文章

  1. 计算机考研:河南有哪些性价比高的学校?
  2. 在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password: YES)
  3. Canvas绘制星球轨迹移动
  4. 大学期末考试综合实训试题一
  5. 某省HW中遇到的提权
  6. Hadoop之HDFS文件操作
  7. AdapterView及其子类之一:基本原理(ListView、ListActivity类型)
  8. Spark入门 - History Server配置使用
  9. eclipse配置maven + 创建maven项目
  10. 一致性哈希算法学习及JAVA代码实现分析