Codeforces Round #837 (Div. 2)
创始人
2024-05-03 10:20:29
0

A. Hossam and Combinatorics

题目链接:Problem - A - Codeforces

样例输入: 

2
5
6 2 3 8 1
6
7 2 8 3 2 10

样例输出:

2
4

题意:给定一个有n个元素的数组,然后让我们求出有多少对(i,j)满足|a[i]-a[j]|=max|a[p]-q[q]|(1<=p,q<=n).

分析:容易发现差的绝对值的最大值一定是数组中的最大值减去最小值得到的,所以我们可以求出来最大值的出现次数cntx和最小值的出现次数cntn,如果最大值等于最小值那么就代表所有的数都是相同的,那么就任意选两个就行,答案就是C(cntn,2)*2,别忘记是带有顺序的,即点对(i,j)和点对(j,i)被看作是不同的点对。如果最大值不等于最小值,那么就随便选一个最大值和一个最小值即可,答案就是cntx*cntn*2.

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{int T;cin>>T;while(T--){int n;scanf("%d",&n);int mn=1e5+1,mx=0,cntn=0,cntx=0;for(int i=1;i<=n;i++){int t;scanf("%d",&t);if(t>mx){mx=t;cntx=1;}else if(t==mx) cntx++;if(t

B. Hossam and Friends

题目链接:Problem - B - Codeforces

样例输入: 

2
3 2
1 3
2 3
4 2
1 2
2 3

样例输出:

4
5

题意:一开始给定一个n和m,n代表人数,编号从1~n,m代表关系数,每对关系给定两个编号x和y,代表编号为x的人和编号为y的人不认识,现在按照编号顺序从左到右站成一排,问有多少个区间[l,r]满足区间内的人都是互相认识的。

分析:我们不妨按照以某个点为左区间的满足题意的区间个数的方法进行统计,用r[i]记录与编号为i的人互不认识的人的编号的最小值,那么对于每一个i所能到达的区间右边界的最大值就是min(r[i~n]),那么以编号i为左边界的满足题意的区间个数就是min(r[i~n])-i,而min(r[i~n])我们可以用ST表处理一下就行。

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1e5+10;
long long r[N],f[N][32];
long long find(int l,int r)
{int t=(int)log2(r-l+1);return min(f[l][t],f[r-(1<>T;while(T--){long long n,m;scanf("%lld%lld",&n,&m);for(int i=1;i<=n;i++) r[i]=n+1;for(int i=1;i<=m;i++){long long x,y;scanf("%lld%lld",&x,&y);long long mn=min(x,y),mx=max(x,y);r[mn]=min(r[mn],mx);}for(int i=1;i<=n;i++)f[i][0]=r[i];for(int i=1;i<=30;i++)for(int l=1;l-1+(1<

C. Hossam and Trainees

题目链接:Problem - C - Codeforces

样例输入: 

2
3
32 48 7
3
14 5 9

样例输出:

YES
NO

题意:给你n个数,问这n个数中是否存在不互质的两个数,存在输出YES,否则输出NO

分析:欧拉筛预处理一下1e5以内的素数,然后直接用map记录含有每个素数因子的出现次数,如果出现次数大于等于2则说明有多个数含有相同的因子,则说明存在不互质的数对,否则就说明不存在。

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1e5+10;
long long prime[N],tt;
bool vis[N];
void init()
{for(int i=2;i>T;init();while(T--){long long n;scanf("%lld",&n);mapmp;bool flag=false;for(int i=1;i<=n;i++){long long t;scanf("%lld",&t);if(flag) continue;for(int j=1;prime[j]*prime[j]<=t;j++)if(t%prime[j]==0){if(mp[prime[j]]){flag=true;break;}while(t%prime[j]==0) t/=prime[j];mp[prime[j]]=1;}if(t!=1){if(mp[t])flag=true;mp[t]=1;}}if(flag) puts("YES");else puts("NO");}return 0;
}

D. Hossam and (sub-)palindromic tree

题目链接:Problem - D - Codeforces

样例输入: 

2
5
abaca
1 2
1 3
3 4
4 5
9
caabadedb
1 2
2 3
2 4
1 5
5 6
5 7
5 8
8 9

样例输出:

3
5

题意:给定一棵由26个英文字符组成的字典树,问由两个节点之间的路径所代表的字符串中的最长回文子序列的长度。

分析:先来探讨一个基本的问题:给定一个长度为n的字符串,如何求这个字符串中的最长回文子序列的长度?

这是一个比较经典的问题,可以用区间DP来求解,设f[i][j]表示从第i个字符到第j个字符中的最长回文子序列的长度,那么分下面两种情况:

(1)第i个字符和第j个字符是相同的,那么就有f[i][j]=2+f[i+1][j-1]

(2)第i个字符和第j个字符是不同的,那么就有f[i][j]=max(f[i+1][j],f[i][j-1])

按照这个方法,我们就能在O(n^2)的复杂度内将这个问题解决

而下面这个问题其实也是类似的,只不过是在树上而已。

拿这个图来说,假如我们要求解节点1和节点5之间的最长回文子序列的长度,那么我们首先要看一下节点1和节点5的字符是否相同,发现都是a,那么结果就变为2+节点3和节点4之间的最长回文子序列的长度。这个过程我们可以用记忆化搜索,如果搜索到了已知答案我们就可以直接返回,否则就继续搜索,因为每个区间只会被更新一次,所以总的复杂度就是O(n^2)。按照刚才的方法去搜索可以发现我们是要用到每个节点的父节点的,所以我们可以直接dfs求出每个节点的父节点。讲解题目一开始所引入的例子就是一个已知字符串序列的最长回文子序列的求法,那么在搜索过程中我们可以用栈来记录从根节点到该节点的路径,那么我们直接对这个问题进行求解就可以求出来任意一个节点到其任意一个父节点之间的最长回文子序列的长度,那么至于不存在祖先关系两个节点之间的最长回文子序列的长度我们就可以按照刚才所讲述的关系一步一步向其祖先节点搜索,直至搜索到一方是另一方的祖先节点,那么我们就可以直接返回答案了。整个过程采用记忆化搜索,总体复杂度就是O(n^2),细节比较多,见代码:

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=4e5+10;
int h[N],e[N],ne[N],idx,fa[N];
int f[2003][2003];//f[i][j]表示节点i到节点j的最长回文序列长度 
char s[N];
int st[N],tt;
void add(int x,int y)
{e[idx]=y;ne[idx]=h[x];h[x]=idx++;
}
void dfs(int x,int ffa)
{fa[x]=ffa;f[x][x]=1;st[++tt]=x;for(int i=tt-2;i>=1;i--)if(s[x]==s[st[i]]) f[x][st[i]]=f[st[i]][x]=2+f[st[i+1]][fa[x]];else f[x][st[i]]=f[st[i]][x]=max(f[x][st[i+1]],f[fa[x]][st[i]]);for(int i=h[x];i!=-1;i=ne[i]){int j=e[i];if(j==ffa) continue;if(s[j]==s[x]) f[j][x]=f[x][j]=2;else f[j][x]=f[x][j]=1;dfs(j,x);}--tt;
}
int fun(int x,int y)//求节点x与节点y之间的最长回文子序列长度
{if(f[x][y]!=-1) return f[x][y];else if(s[x]==s[y]) return f[x][y]=fun(fa[x],fa[y])+2;else return f[x][y]=max(fun(fa[x],y),fun(x,fa[y]));
} 
int main()
{int T;cin>>T;while(T--){int n;scanf("%d%s",&n,s+1);int u,v;for(int i=1;i<=n;i++) h[i]=-1;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)f[i][j]=-1;idx=0;for(int i=1;i

相关内容

热门资讯

最早期的安卓系统,揭秘最早期安... 亲爱的读者,你是否曾好奇过,那个陪伴我们手机成长的安卓系统,它的起源究竟是怎样的呢?今天,就让我们一...
安卓双系统添加应用,轻松实现多... 你有没有想过,你的安卓手机里可以同时运行两个系统呢?听起来是不是很酷?想象一边是熟悉的安卓系统,一边...
pipo安卓进系统慢,探究pi... 最近是不是发现你的Pipo安卓系统更新或者运行起来特别慢?别急,今天就来给你好好分析分析这个问题,让...
怎样使用安卓手机系统,安卓手机... 你有没有发现,安卓手机已经成为我们生活中不可或缺的一部分呢?从早晨闹钟响起,到晚上睡前刷剧,安卓手机...
双系统安卓安装caj,轻松实现... 你有没有想过,你的安卓手机里装上双系统,是不是就能同时享受安卓和Windows系统的乐趣呢?没错,这...
安卓使用ios系统教程,安卓用... 你是不是也和我一样,对安卓手机上的iOS系统充满了好奇?想要体验一下苹果的优雅和流畅?别急,今天我就...
安卓系统gps快速定位,畅享便... 你有没有遇到过这样的情况:手机里装了各种地图导航软件,但每次出门前都要等上好几分钟才能定位成功,急得...
安卓手机系统更新原理,原理与流... 你有没有发现,你的安卓手机最近是不是总在提醒你更新系统呢?别急,别急,让我来给你揭秘一下安卓手机系统...
安卓系统通知管理,全面解析与优... 你有没有发现,手机里的通知就像是一群调皮的小精灵,时不时地跳出来和你互动?没错,说的就是安卓系统的通...
安卓系统手机哪买,揭秘哪里购买... 你有没有想过,拥有一部安卓系统手机是多么酷的事情呢?想象你可以自由安装各种应用,不受限制地探索各种功...
安卓系统 ipv4,基于安卓系... 你知道吗?在智能手机的世界里,有一个系统可是无人不知、无人不晓,那就是安卓系统。而在这个庞大的安卓家...
目前安卓是什么系统,探索安卓系... 亲爱的读者,你是否曾好奇过,如今安卓系统究竟是什么模样?在这个科技飞速发展的时代,操作系统如同人体的...
安卓6.0系统比5.0,从5.... 你有没有发现,自从手机更新了安卓6.0系统,感觉整个人都清爽了不少呢?没错,今天咱们就来聊聊这个话题...
安卓2.36系统升级,功能革新... 你知道吗?最近安卓系统又来了一次大变身,那就是安卓2.36系统升级!这可不是一个小打小闹的更新,而是...
安卓系统源码怎么打开,并可能需... 你有没有想过,安卓系统的源码就像是一扇神秘的门,隐藏着无数的技术秘密?想要打开这扇门,你得掌握一些小...
安卓8.0系统体验视频,智能革... 你有没有听说安卓8.0系统最近可是火得一塌糊涂啊!作为一个紧跟科技潮流的数码达人,我当然要来给你好好...
宣传系统漫画app安卓,探索安... 亲爱的读者们,你是否曾在某个午后,百无聊赖地打开手机,想要寻找一些轻松愉悦的读物?今天,我要给你介绍...
鸿蒙替换安卓系统吗,开启智能生... 你知道吗?最近科技圈里可是炸开了锅,因为华为的新操作系统鸿蒙系统,据说要大举进军手机市场,替换掉安卓...
手机安卓系统深度清理,解锁手机... 手机里的东西是不是越来越多,感觉就像一个装满了杂物的储物柜?别急,今天就来教你一招——手机安卓系统深...
安卓上的windows系统,融... 你有没有想过,在安卓手机上也能体验到Windows系统的魅力呢?没错,这就是今天我要跟你分享的神奇故...