第一次6题纪念第一次6题纪念第一次6题纪念

A - Lexicographic Order

题意
s字符串的字典序是否小于ts字符串的字典序是否小于ts字符串的字典序是否小于t
思路
模拟模拟模拟
时间复杂度:O1O1O1

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\n"
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int>
#define re register int
#define int long long
#define pb push_back
#define y second
#define x first
using namespace std;
const int N = 1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;signed main()
{string s , t ;cin >> s >> t ;if(s < t) puts("Yes") ;else puts("No") ;return 0;
}

B - AtCoder Quiz

题意
给定4个不同的字符串给定4个不同的字符串给定4个不同的字符串
输入三个不同字符串,求没有出现过的那个输入三个不同字符串,求没有出现过的那个输入三个不同字符串,求没有出现过的那个
思路
模拟模拟模拟
时间复杂度:O1O1O1

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\n"
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int>
#define re register int
#define int long long
#define pb push_back
#define y second
#define x first
using namespace std;
const int N = 1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
map<string,int> q ;
signed main()
{string x ;q["ABC"] ++ ;q["ARC"] ++ ;q["AGC"] ++ ;q["AHC"] ++ ;for(int i = 1 ; i <= 3 ; i ++){cin >> x ;q[x] ++ ;}for(auto i : q){if(i.y == 1) {cout << i.x << "\n" ;break ;}}return 0;
}

C - Inverse of Permutation

题意
给定一个n的排列给定一个n的排列给定一个n的排列
求对所有的[1<=i<=n]等于i的下标求对所有的[1 <= i <= n ] 等于i的下标求对所有的[1<=i<=n]等于i的下标
思路
模拟模拟模拟
时间复杂度:OnOnOn

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\n"
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int>
#define re register int
#define int long long
#define pb push_back
#define y second
#define x first
using namespace std;
const int N = 1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
int n ;
int a[N] ;
int q[N] ;
signed main()
{cin >> n ;fer(i,1,n) sf(a[i]) ;fer(i,1,n){q[a[i]] = i ;}fer(i,1,n){cout << q[i] << " " ;}return 0;
}

D - Cutting Woods

题意
一开始有一根木棒一开始有一根木棒一开始有一根木棒
长度为n长度为n长度为n
从1到n编号从1到n编号从1到n编号
输入q个操作输入q个操作输入q个操作

操作1操作1操作1
断开x所在的木棒断开x所在的木棒断开x所在的木棒
[1,n]断开x变成了[1,x][x+1,n][1,n] 断开x变成了 [1,x] [x+1,n][1,n]断开x变成了[1,x][x+1,n]

操作2操作2操作2
询问x所在的区间长度询问x所在的区间长度询问x所在的区间长度

q<=1e5q <= 1e5q<=1e5
n<=1e9n <= 1e9n<=1e9
1<=x<=1e91 <= x <= 1e91<=x<=1e9
思路
有个很重要的性质有个很重要的性质有个很重要的性质
分割之后左边以及右边这个区间的答案是固定的分割之后左边以及右边这个区间的答案是固定的分割之后左边以及右边这个区间的答案是固定的
也就是说答案只跟分割点有关也就是说答案只跟分割点有关也就是说答案只跟分割点有关
比如区间[l,r]分割x变成了[l,x],[x+1,r]比如区间[l,r] 分割x变成了[l,x] , [x+1,r]比如区间[l,r]分割x变成了[l,x],[x+1,r]
可以发现可以发现可以发现
l到x这个区间的询问答案都是x−l+1l到x这个区间的询问答案都是x-l+1l到x这个区间的询问答案都是x−l+1
x+1到r这个区间的询问答案都是r−(x+1)−1x+1到r这个区间的询问答案都是r-(x + 1) - 1x+1到r这个区间的询问答案都是r−(x+1)−1

所以可以考虑二分找到所在区间相邻2个的分割点下标所以可以考虑二分找到所在区间相邻2个的分割点下标所以可以考虑二分找到所在区间相邻2个的分割点下标
先考虑边界问题先考虑边界问题先考虑边界问题
边界无非是0−n+1/0−n/1−n/1−n+1边界无非是0 - n + 1 / 0 - n / 1 - n / 1 - n + 1边界无非是0−n+1/0−n/1−n/1−n+1
这4种的其中一种这4种的其中一种这4种的其中一种

这个时候先假设区间是[1,2],[3,4],[5]这个时候先假设区间是[1,2] , [3,4] , [5]这个时候先假设区间是[1,2],[3,4],[5]

分割点是 0/1 2 4 5/5+1

对于查询2
找到第一个大于等于2的数是2
第一个小于2的数应该是 0/1
答案是2
所以应该是 2 - 0 = 2
左边界应该是0

在考虑查询5
答案是1
找到第一个大于等于5的数是5/6
第一个小于5的数应该是4
所以应该是 5 - 4 = 1
右边界是n

在考虑二分操作的时候 分割点数组保持有序
所以可以用set动态维护

时间复杂度:OnlognOnlognOnlogn

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\n"
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int>
#define re register int
#define int long long
#define pb push_back
#define y second
#define x first
using namespace std;
const int N = 1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
set<int> q ;
int n , t ;
signed main()
{cin >> n >> t ;q.insert(0) ;q.insert(n) ;while(t--){int c , x ;sf(c) , sf(x) ;if(c == 1){q.insert(x) ;}else{cout << *q.lower_bound(x) - *--q.lower_bound(x) << "\n" ;}}return 0;
}

E - Sorting Queries

题意
一开始有一个空的序列一开始有一个空的序列一开始有一个空的序列
q个操作q个操作q个操作

操作1操作1操作1
在序列末尾添加一个数x在序列末尾添加一个数x在序列末尾添加一个数x

操作2操作2操作2
输出序列第一个数并且删除输出序列第一个数并且删除输出序列第一个数并且删除

操作3操作3操作3
给当前序列排序给当前序列排序给当前序列排序

q<=1e5q <= 1e5q<=1e5
x<=1e9x <= 1e9x<=1e9
思路
假设不考虑操作3假设不考虑操作3假设不考虑操作3
可以用数组模拟队列on解决可以用数组模拟队列on解决可以用数组模拟队列on解决

那么队列是一定要使用的那么队列是一定要使用的那么队列是一定要使用的
现在考虑一下怎么维护操作3对队列的影响现在考虑一下怎么维护操作3对队列的影响现在考虑一下怎么维护操作3对队列的影响

队列的2个元素队列的2个元素队列的2个元素
hh代表对头hh代表对头hh代表对头
tt代表队尾tt代表队尾tt代表队尾

排序如果暴力的话On2logn排序如果暴力的话On^2logn排序如果暴力的话On2logn
考虑如何优化考虑如何优化考虑如何优化
有一个很重要的性质是排序的时候有一个很重要的性质是排序的时候有一个很重要的性质是排序的时候
是边插入边排序是边插入边排序是边插入边排序
所以可以用set动态维护所以可以用set动态维护所以可以用set动态维护

然后把对头指向set后面的第一个下标然后把对头指向set后面的第一个下标然后把对头指向set后面的第一个下标
时间复杂度:OnlognOnlognOnlogn

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\n"
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int>
#define re register int
#define int long long
#define pb push_back
#define y second
#define x first
using namespace std;
const int N = 1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;int a[N] ;
multiset<int> q ;
// 带重复元素的set
bool st[N] ;
signed main()
{int hh = 0 , tt = 0 ;int t ;cin >> t ;int k = 1; // k = 1 表示队列第一个数的下标是1int op ;while(t--){sf(op) ;if(op == 1){int x ;sf(x) ;a[++ tt] = x ;// 队尾加入x}else if(op == 2){// 如果排序过if(q.size()){cout << *q.begin() << "\n" ;q.erase(q.begin()) ;// 输入对头并且删除}else {cout << a[k] << "\n" ;st[k] = 1 ;k ++ ;// 没有排序过就输出第一个数// 然后标记这个数没有了// 对头 ++ }}else {for(int i = k ; i <= tt ; i ++) {if(!st[i]) q.insert(a[i]) ;}k = tt + 1 ;// 插入之后 对头指向队尾的下一个下标}}return 0;
}

G - Groups

题意
有1,2,3......n有1,2,3......n有1,2,3......n
n个数n个数n个数
问这n个数可以分为多少组问这n个数可以分为多少组问这n个数可以分为多少组
并且保证每一组的数%m的值没有相等的并且保证每一组的数\%m的值没有相等的并且保证每一组的数%m的值没有相等的
输出每个组的方案输出每个组的方案输出每个组的方案

n<=5000n <= 5000n<=5000
思路
假设先不考虑保证每一组的数%m的值没有相等的假设先不考虑保证每一组的数\%m的值没有相等的假设先不考虑保证每一组的数%m的值没有相等的

那么就是一个很经典的第二类斯特林数那么就是一个很经典的第二类斯特林数那么就是一个很经典的第二类斯特林数
f[i][j]表示前i个数分成j组的方案数f[i][j]表示前i个数分成j组的方案数f[i][j]表示前i个数分成j组的方案数
f[i][j]=f[i−1][j−1]+j∗f[i−1][j]f[i][j] = f[i-1][j-1] +j*f[i-1][j]f[i][j]=f[i−1][j−1]+j∗f[i−1][j]

第i个数单独分成一组是f[i−1][j−1]第i个数单独分成一组是f[i-1][j-1]第i个数单独分成一组是f[i−1][j−1]
或者第i个数分成前面已经有的j组中的其中一组j∗f[i−1][j]或者第i个数分成前面已经有的j组中的其中一组j * f[i-1][j]或者第i个数分成前面已经有的j组中的其中一组j∗f[i−1][j]

那么考虑一下加上题目给的限制条件那么考虑一下加上题目给的限制条件那么考虑一下加上题目给的限制条件
每一组的数%m的值没有相等的每一组的数\%m的值没有相等的每一组的数%m的值没有相等的
也就是说第i个数分成前面已经有的j组中的其中一组也就是说第i个数分成前面已经有的j组中的其中一组也就是说第i个数分成前面已经有的j组中的其中一组
必须保证分到的那个组中没有当前这个数%m的值出现必须保证分到的那个组中没有当前这个数\%m的值出现必须保证分到的那个组中没有当前这个数%m的值出现

所以先维护一个cnt数组所以先维护一个cnt数组所以先维护一个cnt数组
表示a[i]%m的个数表示a[i] \% m的个数表示a[i]%m的个数

在放第i个数的时候如果已经放过了这个数了在放第i个数的时候如果已经放过了这个数了在放第i个数的时候如果已经放过了这个数了
放下一个数的时候就不能在放这个数放下一个数的时候就不能在放这个数放下一个数的时候就不能在放这个数
所以状态方程就变成了所以状态方程就变成了所以状态方程就变成了
f[i][j]=f[i−1][j−1]+k∗f[i−1][j]f[i][j] = f[i-1][j-1] +k*f[i-1][j]f[i][j]=f[i−1][j−1]+k∗f[i−1][j]

但是这样还是有一个问题但是这样还是有一个问题但是这样还是有一个问题
第一层循环枚举的是i也就是这个数第一层循环枚举的是i也就是这个数第一层循环枚举的是i也就是这个数
第二层循环枚举的是j组数第二层循环枚举的是j组数第二层循环枚举的是j组数
我们发现不能不重不漏的进行转移我们发现不能不重不漏的进行转移我们发现不能不重不漏的进行转移
因为必须保证每个数是按照顺序放的因为必须保证每个数是按照顺序放的因为必须保证每个数是按照顺序放的

所以先枚举组数j所以先枚举组数j所以先枚举组数j
在枚举i在枚举i在枚举i
在组数固定情况下在组数固定情况下在组数固定情况下
依次放入每个数即可依次放入每个数即可依次放入每个数即可
k的求法具体细节可以看代码k的求法具体细节可以看代码k的求法具体细节可以看代码
时间复杂度:On2On^2On2

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\n"
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int>
#define re register int
#define int long long
#define pb push_back
#define y second
#define x first
using namespace std;
const int N = 1e6 + 10 , M = 5010 , inf = 0x3f3f3f3f , mod = 998244353 ;
int f[M][M] ;
// 前i个数分成j组的方案数
int n , m ;
int a[N] ;
// 1到i的每个数
int cnt[M] ;
// 每个数 % m的个数
int q[M] ;
// 工具数组
signed main()
{cin >> n >> m ;fer(i,1,n){a[i] = i ;cnt[i % m] ++ ;}f[0][0] = 1 ;  // 初始化for(int j = 1 ; j <= n ; j ++){//  每次固定j组数 memcpy(q,cnt,sizeof cnt) ;// 把cnt数组给q数组for(int i = 1 ; i <= n ; i ++){f[i][j] = (f[i-1][j-1] + f[i-1][j] * (j - ( cnt[a[i] % m] - q[a[i] % m] ) )) % mod;// k = j - ( cnt[a[i] % m] - q[a[i] % m] )// 表示用j所有组减去前面有多少个组放了这个数 % mq[a[i] % m] -- ;// 放了这个数之后 这个数 % m -- // 表示j之前的所有组中放了a[i] % m 的组 ++}}for(int i = 1 ; i <= n ; i ++) cout << f[n][i] % mod << "\n" ;return 0;
}

AtCoder Beginner Contest 217 A B C D E G 题解相关推荐

  1. [2021-09-04 AtCoder Beginner Contest 217] 题解

    文章目录 A - Lexicographic Order B - AtCoder Quiz C - Inverse of Permutation D - Cutting Woods E - Sorti ...

  2. AtCoder Beginner Contest 217

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

  3. AtCoder Beginner Contest 217 D - Cutting Woods(set + 二分查找)

    题目大意 有一根长度为L的木头,这根木头上有L - 1个可以劈的点,对这根木头进行q次操作,操作有两种:操作一是往一个可劈点劈一刀,把这个点所在的木头段劈成两段:操作二是输出一个可劈点所在木头段的长度 ...

  4. AtCoder Beginner Contest 202 D - aab aba baa(组合计数,字典序)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Problem 有 AAA 和 aaa,BBB 个 bbb ,可以使用这 A+BA+BA+B 个字符任 ...

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

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

  6. AtCoder Beginner Contest 198 (A ~ F)题解

    目录 A. Div B. Palindrome with leading zeros C. Compass Walking D. Send More Money E. Unique Color F. ...

  7. AtCoder Beginner Contest 215 G - Colorful Candies 2

    AtCoder Beginner Contest 215 G - Colorful Candies 2 有n个糖果,每个糖果有着一个颜色a[i],每次拿k个糖果期望拿到E(x)个不同颜色的糖果,求出k ...

  8. AtCoder Beginner Contest 215 F - Dist Max 2

    AtCoder Beginner Contest 215 F - Dist Max 2 平面上有一系列的点(xi,yi)(x_i,y_i)(xi​,yi​),定义两点(xi,yi),(xj,yj)(x ...

  9. AtCoder Beginner Contest 215 E - Chain Contestant

    AtCoder Beginner Contest 215 E - Chain Contestant 给出一个只包括A~J的字符串,定义一种子序列为:在这个子序列中,相同的字符必定连续出现,求出这样的子 ...

最新文章

  1. dwa的区别 teb_teb_local_planner安装及使用
  2. leetcode- 两数之和
  3. synergy软件ubuntu配置
  4. 如何应用AutoML加速图机器学习任务的处理?
  5. 用PHP做负载均衡指南
  6. 深度学习之生成对抗网络(7)WGAN原理
  7. vue-cli部署ngixs_Vue-cli项目部署到Nginx
  8. raid-6磁盘阵列损坏导致数据丢失的恢复过程(图文教程)
  9. java : nio 学习
  10. NX(UGS)技术关于我和你顶着忽移不定的云彩
  11. python-flask-uwsgi体验
  12. java面试宝典2019_Java面试宝典2019完整版.doc
  13. arduino 智能车组装步骤_Arduino 自动避障智能小车制作教程
  14. 【微信小程序】微信支付
  15. MAC压缩文件 密码 加密ZIP
  16. 传奇3国际版 单机假设.说明和下载地址
  17. 远程桌面连接发生身份验证错误,提示要求的函数不受支持
  18. 四种方式获取当前电脑的真实IP
  19. 点阵LCD12864的显示原理(不带字库)
  20. maven工程的目录结构

热门文章

  1. openssl给内网IP生成ca证书(ssl证书)
  2. 零输入响应,零状态响应,全响应
  3. 李彦宏说百度吹的牛都实现了,还扔出来一个ACE计划
  4. 我也来读jquery
  5. 服务器开发macbook综述
  6. 有什么方法判断网站后台是用什么语言写的
  7. js面向对象 —— ES6
  8. 最好的文学素材网站有哪些?
  9. 智能优化算法:CEC23组常用测试函数公式介绍
  10. MESH标准配网流程