补题:河南萌新联赛2024第(一)场:河南农业大学

目录

K-图上计数

F-两难抉择新编

G-旅途的终点

D-小蓝的二进制询问

B-爱探险的朵拉


K-图上计数

871e2ece893a451a84dafcad47adaf59.png

思路:观察到可以删除任意边来获得若干连通块,其实就是有n个点,组成两个连通块,求图的代价最大值,与边无关(赛时没看到,在那并查集+dfs。。。),只需要将点平分成两个连通块,求乘积就行。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define MOD 10000000007
#define INF 0x3f3f3f3f
const int N=1e5+5;
void solve()
{
	int n,m;cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int u,v;cin>>u>>v;
    }
    if(n<=1) cout<<0;
    else if(n==2) cout<<1;
    else if(n%2==1) cout<<(n/2)*(n/2+1);
    else if(n%2==0) cout<<(n/2)*(n/2);
}
signed main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
//     int _;cin>>_;while(_--)
    solve();
}

F-两难抉择新编

e2e69f0fcf924e99abd741dc4d1f4aa6.png

思路:暴力题,用一个数组记录异或和,枚举1~x,对其进行加或乘,取最大值即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define MOD 10000000007
#define INF 0x3f3f3f3f
const int N=2e5+5;
int a[N];
void solve()
{
	int n;cin>>n;int sum=0,ans=0;
    for(int i=1;i<=n;i++) cin>>a[i],sum^=a[i];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n/i;j++)
        {
        	ans=max(ans,sum^a[i]^(a[i]+j));
        	ans=max(ans,sum^a[i]^(a[i]*j));
        }
    }
    cout<<ans;
}
signed main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
//     int _;cin>>_;while(_--)
    solve();
}

G-旅途的终点

73c41180d4d342f0a293fb0de49d794e.png

b0a71b6d9c8442488e900b35f76d7ae3.png

思路:注意到eq?%5Csum_%7Bi%3D1%7D%5E%7Bn%7Dai会超过long long,所以在找到答案后直接返回,采用优先队列,当优先队列中的元素个数大于k时,考虑使用生命力来畅游所需生命力少的国家,所需大的国家使用神力抵消,直到所需生命力大于等于总生命力时则无法继续畅游。复杂度:O(nlogn)。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define MOD 10000000007
#define INF 0x3f3f3f3f
const int N=2e5+5;
int a[N];
void solve()
{
	int n,m,k;cin>>n>>m>>k;int sum=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    priority_queue <int,vector<int>,greater<int> >q;//将所需生命力从小到大排,优先抵扣小的
    for(int i=1;i<=n;i++)
    {
        q.push(a[i]);//入队
        if(q.size()>k)//当神力无法全部畅游考虑使用生命力抵扣
        {
        	sum+=q.top();//用生命力畅游当前所需最小的国家
        	q.pop();
        }
        if(sum>=m)//生命力不够直接输出答案
        {
        	cout<<i-1<<endl;return;
        }
    }
    cout<<n<<endl;
}
signed main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
//     int _;cin>>_;while(_--)
    solve();
}

D-小蓝的二进制询问

615ec69c899b4acd84be2b8d92422a71.png

思路:从低位到高位观察,第一位隔两次出现一次1,第二位隔四次出现一次1,第三位隔八次出现一次1........直接计算即可,注意处理余数,求1~r与1~l-1的个数,相减即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mod 998244353
#define INF 0x3f3f3f3f
const int N=1e5+5;
int f(int x)
{
	int res=0,a=2;
	x++;//包含x
	while(a/2<=x)
	{
		res+=(x/a)*(a/2);res%=mod;//计算第a/2位的个数
		res+=max(0,(x%a-(a/2)));res%=mod;//计算余数
	}
}
void solve()
{
	int l,r;cin>>l>>r;
	cout<<f(r)-f(l-1)<<endl;
}
signed main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int _;cin>>_;while(_--)
    solve();
}

B-爱探险的朵拉

思路:最多可以探险的关卡数就是各个关卡所组成的最大环或者最长链的大小,官方题解是拓扑排序,并更新环的点的数量。应该是数据弱了,dfs直接搜也能过。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define MOD 10000000007
#define INF 0x3f3f3f3f
const int N=1e5+5;
int a[N],b[N],ma=0;
void dfs(int fi,int x,int l)
{
    ma=max(ma,l);
    if(b[x]!=fi)
    {
       b[x]=fi;//更新每个关卡的前置关卡,判断是否成环 
       dfs(fi,a[x],l+1);
    }
}
void solve()
{
	int n;cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        if(!b[i]) dfs(i,i,0);
    }
    cout<<ma;
}
signed main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    // int _;cin>>_;while(_--)
    solve();
}

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值