2020牛客暑期多校训练营(第四场)BCFH
BCFH
B. Basic God Problem
题意
给出c和n,求fc(n)。
题解
递归到最后 fc 函数肯定等于1,那么就变成了求c被乘了几次,只要找到 x 最多能被分解成多少个数相乘就好了。预处理用线性筛求出每个数最多能被分解成多少个数相乘,快速幂求出解。
代码


1 #include<bits/stdc++.h>
2 #define ll long long
3 #define pb push_back
4 #define ft first
5 #define sd second
6 #define pii pair<int,int>
7 #define pll pair<ll,ll>
8 using namespace std;
9
10 ll st[1001000];
11 ll prime[1001000];
12 ll d[1001000];
13 ll cnt;
14 const ll mod=1e9+7;
15 void Prime(ll n)
16 {
17 cnt=0;
18 for(ll i=2;i<=n;i++){
19 if(!st[i]) prime[cnt++]=i,d[i]=1;
20 for(int j=0;prime[j]*i<=n;j++){
21 st[prime[j]*i]=1;
22 d[prime[j]*i]=d[i]+1;
23 if(i%prime[j]==0) break;
24 }
25 }
26 }
27 ll quick(ll a,ll b)
28 {
29 ll res=1;
30 a=a%mod;
31 while(b){
32 if(b&1) res=(res*a)%mod;
33 a=(a*a)%mod;
34 b>>=1;
35 }
36 return res%mod;
37 }
38 int main()
39 {
40 ios::sync_with_stdio(false);
41 cin.tie(0);
42 cout.tie(0);
43 Prime(1000000);
44 for(ll i=1;i<=10;i++) cout<<d[i]<<endl;
45 int t;
46 cin>>t;
47 while(t--){
48 ll n,c;
49 cin>>n>>c;
50 cout<<quick(c,d[n])<<endl;
51 }
52 return 0;
53 }
C. Count New String
题意
题解
• 核心点 1
• 核心点 2
• 所以我们要考虑这个字典树本质不同的子串
代码


1 #include<bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4
5 const int maxn=1e6+10;
6
7 struct state
8 {
9 int mxlen,link;
10 int cnt;
11 int nt[26];
12 }st[maxn<<1];
13
14 int sz,last,len;
15 char s[maxn];
16
17 inline void sam_init()
18 {
19 st[0].mxlen=0;
20 st[0].link=-1;
21 sz=1;
22 last=0;
23 }
24
25 inline void sam_extend(int c)
26 {
27 int cur=sz++;
28 st[cur].mxlen=st[last].mxlen+1;
29 st[cur].cnt=1;
30 int p=last;
31 while(p!=-1&&!st[p].nt[c]){
32 st[p].nt[c]=cur;
33 p=st[p].link;
34 }
35 if(p==-1) st[cur].link=0;
36 else{
37 int q=st[p].nt[c];
38 if(st[p].mxlen+1==st[q].mxlen) st[cur].link=q;
39 else{
40 int clone=sz++;
41 st[clone].mxlen=st[p].mxlen+1;
42 memcpy(st[clone].nt,st[q].nt,sizeof(st[q].nt));
43 st[clone].link=st[q].link;
44 while(p!=-1&&st[p].nt[c]==q){
45 st[p].nt[c]=clone;
46 p=st[p].link;
47 }
48 st[q].link=st[cur].link=clone;
49 }
50 }
51 last=cur;
52 }
53
54 int nt[maxn][10],id[maxn];
55 //nx[i][j]第i个位置(包括)后首次出现大于等于j的位置
56
57 int main()
58 {
59 cin>>s+1;
60 sam_init();
61 int n=strlen(s+1);
62 for(int i=0;i<10;i++) nt[n+1][i]=n+1;
63 for(int i=n;i>=1;i--){
64 for(int j=0;j<10;j++) nt[i][j]=nt[i+1][j];
65 nt[i][s[i]-'a']=i;
66 for(int j=8;j>=0;j--) nt[i][j]=min(nt[i][j],nt[i][j+1]);
67 }
68 id[n+1]=last;
69 for(int i=n;i>=1;i--){
70 int pos=nt[i+1][s[i]-'a'];
71 last=id[pos];
72 for(int j=i;j<pos;j++) sam_extend(s[i]-'a');
73 id[i]=last;
74 }
75 ll ans=0;
76 for(int i=1;i<=sz;i++){
77 ans+=st[i].mxlen-st[st[i].link].mxlen;
78 }
79 cout<<ans<<endl;
80 return 0;
81 }
单调队列+SAM


1 #include<bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4
5 const int maxn=1e6+10;
6
7 struct state
8 {
9 int mxlen,link;
10 int cnt;
11 int nt[26];
12 }st[maxn<<1];
13
14 int sz,last,len;
15 char s[maxn];
16
17 inline void sam_init()
18 {
19 st[0].mxlen=0;
20 st[0].link=-1;
21 sz=1;
22 last=0;
23 }
24
25 inline void sam_extend(int c)
26 {
27 int cur=sz++;
28 st[cur].mxlen=st[last].mxlen+1;
29 st[cur].cnt=1;
30 int p=last;
31 while(p!=-1&&!st[p].nt[c]){
32 st[p].nt[c]=cur;
33 p=st[p].link;
34 }
35 if(p==-1) st[cur].link=0;
36 else{
37 int q=st[p].nt[c];
38 if(st[p].mxlen+1==st[q].mxlen) st[cur].link=q;
39 else{
40 int clone=sz++;
41 st[clone].mxlen=st[p].mxlen+1;
42 memcpy(st[clone].nt,st[q].nt,sizeof(st[q].nt));
43 st[clone].link=st[q].link;
44 while(p!=-1&&st[p].nt[c]==q){
45 st[p].nt[c]=clone;
46 p=st[p].link;
47 }
48 st[q].link=st[cur].link=clone;
49 }
50 }
51 last=cur;
52 }
53
54 int id[maxn];
55
56 int main()
57 {
58 cin>>s+1;
59 sam_init();
60 int n=strlen(s+1);
61 stack<int>ss;
62 ss.push(n+1);
63 id[n+1]=last;
64 for(int i=n;i>=1;i--){
65 while(ss.size()!=1&&s[ss.top()]<s[i]) ss.pop();
66 int pos=ss.top();
67 last=id[pos];
68 for(int j=i;j<pos;j++) sam_extend(s[i]-'a');
69 id[i]=last;
70 ss.push(i);
71 }
72 ll ans=0;
73 for(int i=1;i<=sz;i++){
74 ans+=st[i].mxlen-st[st[i].link].mxlen;
75 }
76 cout<<ans<<endl;
77 return 0;
78 }
F. Finding the Order
题意
有两条平行的线AB和CD,给出AC, AD, BC, BD 的长度,分别为a, b, c, d。问是AB//CD,还是AB//DC。
题解
- 这是一个神奇的题目,我是把所有情况画出来记录,毕竟暴力出奇迹嘛^_^
- 发现自己是憨憨,看了其他巨巨的题解发现自己的方法好蠢,我连小学数学的水平都没有┭┮﹏┭┮ ,这个解法来自@Harris-H。根据两边之和大于第三边,直接比较AC+BD和AB+BC的长度就好了,长的是四边形的交线,就可以判断是CD还是DC了。
代码
菜鸡本人的代码


1 #include<bits/stdc++.h>
2 #define ll long long
3 #define pb push_back
4 #define ft first
5 #define sd second
6 #define pii pair<int,int>
7 #define pll pair<ll,ll>
8 using namespace std;
9
10 int main()
11 {
12 ios::sync_with_stdio(false);
13 cin.tie(0);
14 cout.tie(0);
15 int t;
16 cin>>t;
17 while(t--){
18 int a,b,c,d;
19 cin>>a>>b>>c>>d;
20 if(b>a&&c>d&&b>d||a>b&&c>d&&c>a||b>a&&d>c&&b>d||a==b&&c>d&&c>a||c==d&&b>a&&b>d) cout<<"AB//CD"<<endl;
21 else cout<<"AB//DC"<<endl;
22 }
23 return 0;
24 }
巨巨的代码


1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
5 #define mst(a) memset(a,0,sizeof a)
6 #define lx x<<1
7 #define rx x<<1|1
8 #define reg register
9 #define PII pair
10 #define fi first
11 #define se second
12 #define pb push_back
13 int main(){
14 int t;
15 cin>>t;
16 while(t--){
17 int a,b,c,d;
18 cin>>a>>b>>c>>d;
19 puts(b+c>a+d?"AB//CD":"AB//DC");
20 }
21 return 0;
22 }
H. Haeder Gcd Problem
题意
集合A和B都是{1,2,.....,n}的子集,A∩B≠∅。问A和B最多有多少对数GCD(Ap,Bq)>1。
题解
所有gcd>1的两个数肯定是倍数关系,最小肯定是本身和2倍。越大的数能和他匹配的就会越少,为了简单,从大的数往小的数匹配。先用线性筛O(n)预处理出1-n之间的质数,然后找到小于n的质数最大,并且要有至少一个数可以和他配对。从这个质数开始往下计算,如果有偶数个可以和该质数配对的,那就直接记录下来;如果是奇数个,最简单的方法是将这个数的二倍放弃,剩下的记录下来。因为是2的倍数,肯定存在,并且方便计算。
代码


1 #include<bits/stdc++.h>
2 #define ll long long
3 #define pb push_back
4 #define ft first
5 #define sd second
6 #define pii pair<int,int>
7 #define pll pair<ll,ll>
8 using namespace std;
9
10 ll st[200100];
11 ll prime[200100];
12 ll cnt;
13
14 void Prime(ll n)
15 {
16 cnt=0;
17 for(ll i=2;i<=n;i++){
18 if(!st[i]) prime[cnt++]=i;
19 for(int j=0;prime[j]*i<=n;j++){
20 st[prime[j]*i]=1;
21 if(i%prime[j]==0) break;
22 }
23 }
24 }
25
26 ll quick(int a,int b)
27 {
28 int res=1;
29 while(b){
30 if(b&1) res=(res*a);
31 a=(a*a);
32 b>>=1;
33 }
34 return res;
35 }
36
37 bool vis[200100];
38 vector<int>v[200100];
39
40 int main()
41 {
42 ios::sync_with_stdio(false);
43 cin.tie(0);
44 cout.tie(0);
45 int t;
46 cin>>t;
47 Prime(200000);
48 while(t--){
49 memset(vis,0,sizeof(vis));
50 int n;
51 cin>>n;
52 for(int i=0;i<=n;i++) v[i].clear();
53 int k=cnt-1;
54 for(int i=0;i<cnt;i++){
55 if(prime[i]>n) {k=i-1;break;}
56 }
57 int ans=0;
58 for(int i=k;i>=0;i--){
59 int p=n/prime[i],x=0;
60 for(int j=1;j<=n/prime[i];j++)
61 if(!vis[prime[i]*j]) x++;
62 if(x&1){
63 int flag=0;
64 if(n/prime[i]<2) continue;
65 for(int j=1;j<=n/prime[i];j++){
66 if(!flag&&!vis[prime[i]*j]&&(prime[i]*j)%2==0) flag=1; //删掉一个2的倍数
67 else if(!vis[prime[i]*j]) {
68 vis[prime[i]*j]=1;
69 v[i].push_back(prime[i]*j);
70 }
71 }
72 }
73 else{
74 for(int j=1;j<=n/prime[i];j++)
75 if(!vis[prime[i]*j]) {
76 vis[prime[i]*j]=1;
77 v[i].push_back(prime[i]*j);
78 }
79 }
80 }
81 for(int i=0;i<=k;i++){
82 ans+=v[i].size()/2;
83 }
84 cout<<ans<<endl;
85 for(int i=0;i<=k;i++){
86 for(int j=1;j<v[i].size();j+=2){
87 cout<<v[i][j-1]<<' '<<v[i][j]<<endl;
88 }
89 }
90 }
91 return 0;
92 }
2020牛客暑期多校训练营(第四场)BCFH的更多相关文章
- 2020牛客暑期多校训练营(第一场)H Minimum-cost Flow
Minimum-cost Flow 题目:给n个点,m条边.接下来m行包含(a,b,c),即a,b之间有单位流量代价为c的边.接下来有q个问题,每个问题给定(x,y),即假设每条边的容量为x/y时,从 ...
- 2020牛客暑期多校训练营(第二场) Boundary
传送门:Boundary 题意:给你n个点的坐标,问最多有多少个点可以在同一个圆上,(0,0)必须在这个圆上. 题解:三个点确定一个圆,所以暴力枚举两个点和(0,0)组成的圆,如果三个点不共线的话, ...
- 2020牛客暑期多校训练营(第一场)Easy Integration
传送门:J. Easy Integration 题意:给你n,求这个积分,最后的结果分子是记为p,分母记为q. 求(p*q-1)mod 998244353. 题解:比赛完看到巨巨说这是贝塔函数,我一搜 ...
- 2020牛客暑期多校训练营 (第二场) All with Pairs
传送门:All with Pairs 题意:给你n个字符串,求出,f(si,sj)的意思是字符串 si 的前缀和字符串 sj 后缀最长相等部分. 题解:先对所有的字符串后缀hash,用map记录每个h ...
- 2020牛客暑期多校训练营(第二场)Fake Maxpooling
传送门:Fake Maxpooling 题意:给出矩阵的行数n和列数m,矩阵 Aij = lcm( i , j ) ,求每个大小为k*k的子矩阵的最大值的和. 题解:如果暴力求解肯定会t,所以要智取 ...
- 2020牛客暑期多校训练营(第二场) F.Fake Maxpooling (单调队列)
题意:有一个\(n\)x\(m\)的矩阵,\(A_{i,j}=lcm(i,j)\),对于每个\(k\)x\(k\)的子矩阵,其最大元素贡献给答案,求答案的最大值. 题解:矩阵构成我们直接\(i*j/g ...
- 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)
题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9: 对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可. 后者mod=1e9,5才 ...
- 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...
- 2019牛客暑期多校训练营(第一场) B Integration (数学)
链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...
随机推荐
- 如何在 Vite 中使用 Element UI + Vue 3
在上篇文章<2021新年 Vue3.0 + Element UI 尝鲜小记>里,我们尝试使用了 Vue CLI 创建 Vue 3 + Element UI 的项目,而 Vue CLI 实际 ...
- Netty入门一:服务端应用搭建 & 启动过程源码分析
最近周末也没啥事就学学Netty,同时打算写一些博客记录一下(写的过程理解更加深刻了) 本文主要从三个方法来呈现:Netty核心组件简介.Netty服务端创建.Netty启动过程源码分析 如果你对Ne ...
- SAP FTP FOR ABAP programing
近来忙的不可开交,忙的一塌糊涂,呵呵,今天怀揣愧疚之心,上来分享博文一篇,算是对自己的一点安慰. 首先在SAP系统中提供了很多的FTP示例程序,如下: RSFTP001 SAPFT ...
- BDC应用
第一步:SHDB或者是SM35进入BDC录制事务.开始录制. 第二部:保存录制的记录. 第三步:在你自己的程序中定义一个内表如:ITAB TYPE TABLE OF BDCDATA. 再定义一个工作空 ...
- oracle ORA-00060死锁查询、表空间扩容
--查看被锁住的表 select b.owner,b.object_name,a.session_id,a.locked_mode from v$locked_object a,dba_objects ...
- ES入门及安装软件
es介绍 Elasticsearch,简称es,是一款高扩展的分布式全文检索引擎.它可以近乎实时的存储,检索数据.es是面向文档型的数据库,一条数据就是一个文档,用json做为文档序列化的格式.es是 ...
- Linux磁盘的分区操作
1.Linux磁盘分区介绍 Linux磁盘分区主要有两种方式,一种是MBR,另一种是GPT.根据Linux磁盘分的大小,来选择一种分区方式. --MBR分区格式:最大支持 2 TB 的磁盘.--GPT ...
- 浅析Redis与IO多路复用器原理
为什么Redis使用多路复用I/O Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导 ...
- get_or_create update_or_create
django/query.py at master · django/django https://github.com/django/django/blob/master/django/db/mod ...
- kettle 连接oracle12c问题解决办法:
在oracle的安装文件目录......\NETWORK\ADMIN\sqlnet.ora 文件中添加该语句:SQLNET.ALLOWED_LOGON_VERSION_SERVER = 8window ...