前面的碎碎念:
题目比较简单,比赛主要还是考验手速和准确率。但是个人不太适应这种函数式编程,而且牛客的函数式编程还不像力扣那样提供在线运行功能,所以也不能进行输出Debug调试。
题解部分:
A-找卧底
要求时间复杂度O(n),空间复杂度O(1),乍一看没什么想法。后来仔细读题发现前n个人选的数字是1-n的一个全排列,因此我们把所有数字相加后,减去(1+2+...+n),就是多出来的那个数字了。
时间复杂度:O(n)。
代码部分:
class Solution {
public:
/**
*
* @param n int整型
* @param a int整型vector
* @return int整型
*/
int search(int n, vector<int>& a) {
int i,ans;
long long s=0;
for(i=0;i<a.size();i++)s+=a[i];
ans=s-(1+(long long)n)*n/2;
return ans;
}
};B-父子情深
以x为根的子树,其所有结点的DFS序一定是一段连续的区间,因此我们先处理出DFS序,然后对于每个询问,使用差分数组对其子树对应区间进行区间加操作。询问结束后,我们利用差分数组得到DFS序的值,然后把每个DFS序的值再映射回对应结点就行了。
时间复杂度:O(n+q)。
代码部分:
/**
* struct Point {
* int x;
* int y;
* };
*/
class Solution {
public:
/**
* 从 1 到 n 每个结点的权值。
* @param n int整型
* @param Edge Point类vector (u, v) 集合
* @param q int整型
* @param Query Point类vector Point.x 为题中 r, Point.y为题中 v
* @return long长整型vector
*/
long S[100005]={0},ans[100005];
int Left[100005],Right[100005],V[100005],t=0;
vector<int>R[100005];
void DFS(int x,int pre)
{
int i,j;
Left[x]=++t,V[t]=x;
for(i=0;i<R[x].size();i++)
{
j=R[x][i];
if(j!=pre)DFS(j,x);
}
Right[x]=t;
}
vector<long> solve(int n, vector<Point>& Edge, int q, vector<Point>& Query) {
vector<long>Ans;
Point p;
int i,l,r;
for(i=0;i<Edge.size();i++)
{
p=Edge[i];
R[p.x].push_back(p.y),R[p.y].push_back(p.x);
}
DFS(1,0);
for(i=0;i<q;i++)
{
p=Query[i];
l=Left[p.x],r=Right[p.x];
S[l]+=p.y,S[r+1]-=p.y;
}
for(i=1;i<=n;i++)S[i]+=S[i-1],ans[V[i]]=S[i];
for(i=1;i<=n;i++)Ans.push_back(ans[i]);
return Ans;
}
};C-旋转跳跃
对于这m对(x,y),我们就让x结点与y结点连一条边,其n个结点会形成若干个连通块,连通块内所有结点的值属于同一个集合。因此我们可以利用并查集处理出每个结点对应的集合(连通块)编号,再使用一个vector容器把各个结点的值存入对应的集合。我们对每个集合进行排序,然后贪心的从集合里取数字即可。具体操作为用变量i从n遍历到1,令ans[i]为i号结点属于的集合里的最大值,然后再把此最大值从该集合中删除。
时间复杂度:O(m+nlog(n))。
代码部分:
/**
* struct Point {
* int x;
* int y;
* };
*/
class Solution {
public:
/**
* 返回牛牛所能得到的字典序最小的排列
* @param n int整型
* @param m int整型
* @param perm int整型vector
* @param Pair Point类vector
* @return int整型vector
*/
int V[100005],ans[100005];
int find(int a)
{
if(V[a]==a)return a;
return V[a]=find(V[a]);
}
vector<int>R[100005];
vector<int> solve(int n, int m, vector<int>& perm, vector<Point>& Pair) {
int i,j,a,b;
Point p;
vector<int>Ans;
for(i=1;i<=n;i++)V[i]=i;
for(i=0;i<m;i++)
{
p=Pair[i];
a=find(p.x),b=find(p.y);
if(a!=b)V[a]=b;
}
for(i=1;i<=n;i++)a=find(i),R[a].push_back(perm[i-1]);
for(i=1;i<=n;i++)sort(R[i].begin(),R[i].end());
for(i=n;i>=1;i--)
{
a=find(i),j=R[a].size();
ans[i]=R[a][j-1],R[a].pop_back();
}
for(i=1;i<=n;i++)Ans.push_back(ans[i]);
return Ans;
}
};完结撒花,若有疏漏之处,还望大佬轻喷。

京公网安备 11010502036488号