文章目录

  • A - Lexicographic Order
  • B - AtCoder Quiz
  • C - Inverse of Permutation
  • D - Cutting Woods
  • E - Sorting Queries
  • F - Make Pair
  • G - Groups

网址链接

A - Lexicographic Order

签到题

#include <cstdio>
#include <iostream>
using namespace std;
int main() {string s, t;cin >> s >> t;if( s < t ) printf( "Yes\n" );else printf( "No\n" );return 0;
}

B - AtCoder Quiz

签到题

#include <cstdio>
#include <iostream>
using namespace std;
char s1[10], s2[10], s3[10];int main() {scanf( "%s %s %s", s1, s2, s3 );if( 'R' != s1[1] and 'R' != s2[1] and 'R' != s3[1] )printf( "ARC\n" );if( 'B' != s1[1] and 'B' != s2[1] and 'B' != s3[1] )printf( "ABC\n" );if( 'H' != s1[1] and 'H' != s2[1] and 'H' != s3[1] )printf( "AHC\n" );if( 'G' != s1[1] and 'G' != s2[1] and 'G' != s3[1] )printf( "AGC\n" );return 0;
}

C - Inverse of Permutation

签到题

#include <cstdio>
#define maxn 200005
int n;
int p[maxn], ans[maxn];int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%d", &p[i] ), ans[p[i]] = i;for( int i = 1;i <= n;i ++ )printf( "%d ", ans[i] );return 0;
}

D - Cutting Woods

签到题

刚开始想歪了,打算不思考直接暴力线段树cao

后来一看1e9的长度,打扰了

再一想,直接set不也可以做到线段树的功能吗

直接把操作点扔进去,找左右最近的分割点即可

#include <set>
#include <cstdio>
using namespace std;
set < int > s;
int n, Q, c, x;int main() {scanf( "%d %d", &n, &Q );s.insert( 0 ), s.insert( n );while( Q -- ) {scanf( "%d %d", &c, &x );if( c == 1 ) s.insert( x );else {auto l = s.lower_bound( x );auto r = l; l --;printf( "%d\n", *r - *l );}}return 0;
}

E - Sorting Queries

签到题

可能会被排序操作吓到TLE

实际上转个弯就知道序列一定是前面有序后面无序的状态

那么分开存进队列即可,遇到排序就把无序的全都丢进有序队列

每个点最多被操作入队两次

复杂度只有有序队列的log罢了

这都是表面上吓唬人的

#include <queue>
#include <cstdio>
using namespace std;
priority_queue < int, vector < int >, greater < int > > q;
queue < int > New;
int Q, opt, x;int main() {scanf( "%d", &Q );while( Q -- ) {scanf( "%d", &opt );switch( opt ) {case 1 : {scanf( "%d", &x );New.push( x );break;}case 2 : {if( ! q.empty() )printf( "%d\n", q.top() ), q.pop();else printf( "%d\n", New.front() ), New.pop();break;}case 3 : {while( ! New.empty() )q.push( New.front() ), New.pop();break;}}}
}

F - Make Pair

中档题

必须要两人是好关系,并且相邻才行

果断区间dpdpdp,根据范围200200200果断猜测时间复杂度应为O(N3)/O(N3log⁡N)O(N^3)/O(N^3\log N)O(N3)/O(N3logN)

dpi,j:[i,j]dp_{i,j}:[i,j]dpi,j​:[i,j]区间的人都成功配对离开的方案数,答案自然为dp1,2ndp_{1,2n}dp1,2n​

考虑枚举与iii配对的是kkk,则kkk将区间[i,j][i,j][i,j]隔绝成两个互相独立的子问题,dpi+1,k−1;;dpk+1,rdp_{i+1,k-1};;dp_{k+1,r}dpi+1,k−1​;;dpk+1,r​

定义dpi+1,i=1dp_{i+1,i}=1dpi+1,i​=1

假设[i+1,k−1][i+1,k-1][i+1,k−1]配对个数为x(k−1−(i+1)+1=k−i−1)x(k-1-(i+1)+1=k-i-1)x(k−1−(i+1)+1=k−i−1),[k+1,r][k+1,r][k+1,r]的配对个数为y(r−(k+1)+1=r−k)y(r-(k+1)+1=r-k)y(r−(k+1)+1=r−k)

dpi,j=∑k=i+1rdpi+1,k−1∗dpk+1,r∗(x+y+1y)dp_{i,j}=\sum_{k=i+1}^rdp_{i+1,k-1}*dp_{k+1,r}*\binom{x+y+1}{y}dpi,j​=k=i+1∑r​dpi+1,k−1​∗dpk+1,r​∗(yx+y+1​)

(x+y+1y)\binom{x+y+1}{y}(yx+y+1​):区间[i,j][i,j][i,j]的配对次数为x+y+1x+y+1x+y+1(i,ki,ki,k的一次配对),从中选择yyy次操作右子区间

为什么不是从中选择xxx次操作左子区间?

因为左子区间的操作事关i,ki,ki,k的相邻问题,而右子区间无关

必须左子区间都操作完了才能操作(i,k)(i,k)(i,k)配对

所以说就不可能出现最后xxx次操作全都是操作左子区间,反而先操作(i,k)(i,k)(i,k)的配对,这样是错误的,那么选xxx的组合数(x+y+1x)\binom{x+y+1}{x}(xx+y+1​)计算的方案数就是错误的

选择右子区间操作的轮数后,剩下的x+1x+1x+1位置就固定了,最后一个一定是(i,k)(i,k)(i,k)的配对

#include <cstdio>
#define int long long
#define mod 998244353
#define maxn 405
int fac[maxn], inv[maxn];
bool good[maxn][maxn];
bool vis[maxn][maxn];
int dp[maxn][maxn];
int n, m;int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}void init() {fac[0] = inv[0] = 1;for( int i = 1;i < maxn;i ++ ) fac[i] = fac[i - 1] * i % mod;inv[maxn - 1] = qkpow( fac[maxn - 1], mod - 2 );for( int i = maxn - 2;i;i -- )inv[i] = inv[i + 1] * ( i + 1 ) % mod;
}int C( int n, int m ) {return fac[n] * inv[m] % mod * inv[n - m] % mod;
}int dfs( int l, int r ) {if( vis[l][r] ) return dp[l][r];if( l > r ) return vis[l][r] = dp[l][r] = 1;int &ans = dp[l][r];for( int i = l + 1;i <= r;i += 2 ) {if( ! good[l][i] ) continue;int x = i - l - 1 >> 1, y = r - i >> 1;ans = ( ans + dfs( l + 1, i - 1 ) * dfs( i + 1, r ) % mod * C( x + y + 1, y ) ) % mod; }vis[l][r] = 1;return ans;
}signed main() {init();scanf( "%lld %lld", &n, &m );for( int i = 1, a, b;i <= m;i ++ ) {scanf( "%lld %lld", &a, &b );good[a][b] = good[b][a] = 1;}n <<= 1;printf( "%lld\n", dfs( 1, n ) );return 0;
}

G - Groups

简单题

设dpi,j:dp_{i,j}:dpi,j​: 前iii个数一共使用了jjj个非空集合

那么转移只会分为两种

  • iii单独成一个新集合

    • dpi,j+=dpi−1,j−1dp_{i,j}+=dp_{i-1,j-1}dpi,j​+=dpi−1,j−1​
  • iii放进前jjj个集合中的某一个
    • 集合无差别
    • 每一个取模mmm相同的数都在不同的集合
    • 前面与iii同余的个数显然为⌊i−1m⌋\lfloor\frac{i-1}{m}\rfloor⌊mi−1​⌋
    • 不能放那些数所在的集合,剩下的集合都是可以放的
    • dpi,j+=dpi−1,j∗max⁡(0,j−⌊i−1m⌋)dp_{i,j}+=dp_{i-1,j}*\max(0,j-\lfloor\frac{i-1}{m}\rfloor)dpi,j​+=dpi−1,j​∗max(0,j−⌊mi−1​⌋)
#include <cstdio>
#include <iostream>
using namespace std;
#define int long long
#define mod 998244353
#define maxn 5005
int n, m;
int dp[maxn][maxn];signed main() {scanf( "%lld %lld", &n, &m );dp[0][0] = 1;for( int i = 1;i <= n;i ++ )for( int j = 1;j <= i;j ++ )dp[i][j] = ( dp[i - 1][j - 1] + dp[i - 1][j] * max( 0ll, j - ( i - 1 ) / m ) ) % mod;for( int i = 1;i <= n;i ++ )printf( "%lld\n", dp[n][i] );return 0;
}

说实话,我觉得F G的题目分值给反了,前面竟然全是签到水题,后面的经典DP还是可以给个好评的

[2021-09-04 AtCoder Beginner Contest 217] 题解相关推荐

  1. Caddi Programming Contest 2021(AtCoder Beginner Contest 193) 题解

    Caddi Programming Contest 2021(AtCoder Beginner Contest 193) A - Discount 打折浮点数除即可 B - Play Snuke 枚举 ...

  2. AtCoder Beginner Contest 197 题解(A ~ F)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A - Rotate B - Visibility C - ORXOR D - Opposite ...

  3. Panasonic Programming Contest (AtCoder Beginner Contest 195) 题解

    文章目录 A - Health M Death B - Many Oranges C - Comma D - Shipping Center E - Lucky 7 Battle F - Coprim ...

  4. AtCoder Beginner Contest 217 A B C D E G 题解

    第一次6题纪念第一次6题纪念第一次6题纪念 A - Lexicographic Order 题意: s字符串的字典序是否小于ts字符串的字典序是否小于ts字符串的字典序是否小于t 思路: 模拟模拟模拟 ...

  5. AtCoder Beginner Contest 096 题解

    比赛地址 https://abc096.contest.atcoder.jp A - Day of Takahashi 题目大意 我们把月和日相同的日期叫做"Takahashi日" ...

  6. freee Programming Contest 2022(AtCoder Beginner Contest 264) 题解 (A~D)

    A - "atcoder".substr() Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100100 points ...

  7. AtCoder Beginner Contest 168题解

    这里写目录标题 A - ∴ (Therefore) 代码 B - ... (Triple Dots) 代码 C - : (Colon) 代码 D - .. (Double Dots) 题意 题解 代码 ...

  8. AtCoder Beginner Contest 153 题解

    题解链接:题解链接 RD是输入,OT是输出 A – SERVAL VS MONSTER 链接: A题 题意: 给你怪物血量H和攻击一次扣A血,问至少要攻击几次能使怪物的血量小于或者等于0 解法: 按题 ...

  9. AtCoder Beginner Contest 217

    更新中- A - Lexicographic Order 题目大意: 给定两个字符串 S 和 T ,判断两者字典序的大小关系. 大致思路: 常规比较字典序. char[] 实现: #include & ...

最新文章

  1. WTForms 小计1 forms
  2. GitHub移动端正式发布
  3. 切图工具优化的几点总结
  4. 从机器学习谈起(机器学习简介)
  5. 计算机组成原理数据冒险的解决nop,计算机组成原理实验讲义(103页)-原创力文档...
  6. 高手都不用dw_雅诗兰黛DW粉底液好用吗?雅诗兰黛DW粉底液如何辨别真假?
  7. MyBatis学习总结(16)——Mybatis使用的几个建议
  8. 游标定位:Cursor类
  9. 【codevs1282】约瑟夫问题
  10. vs code html插件_VS插件CodeRush全新发布v20.1.7|支持HTML
  11. 《数字图像处理》读书笔记:第1章 绪论
  12. 施耐德PLC Unity Pro xl 软件使用一
  13. 【Matlab】根据excel画折线图和柱状图
  14. Tensorflow Serving初体验
  15. 狼性精神——《世界上最伟大的推销员》
  16. 【Flink】需求实现之独立访客数量的计算 和 布隆过滤器的原理及使用
  17. Spring Security 安全框架
  18. Linux 运维常见英文单词
  19. 世界十大经典汽车赛道盘点
  20. 创客平台靠什么盈利?

热门文章

  1. 马斯克又要搞事情,不锈钢材质的Space X“星际飞船”正式亮相
  2. php用switch编写车费的输出,PHP Switch语句在实际代码中的应用
  3. ctf php sql注入,CTF—攻防练习之HTTP—SQL注入(SSI注入)
  4. 深度学习 占用gpu内存 使用率为0_深度解析MegEngine亚线性显存优化技术
  5. python distplot 图_Python可视化23 |seaborn.distplot公司单变量分布图(直方图|核密度图),23seaborndistplot...
  6. php header会重定向吗,php – 可以依靠header()重定向来结束程序流吗?
  7. php mysql 云虚拟机_虚拟机+apache+php+mysql 环境安装配置
  8. react全局状态管理_rxv: 在React中用Vue3的reactivity包实现状态管理。
  9. css 旋转45_CSS教程——第14期
  10. C++ vector容器中用erase函数和迭代器删除重复元素问题分析