2022牛客寒假1-3部分题解

第二场

        K-Tokitsukaze and Synthesis and Traits_2023牛客寒假算法基础集训营2 (nowcoder.com)

                (1)解题思路

                        直接把度数小的点向度数大的点连边,若问度数小的点,那么询问均摊下来小于根号M的,问度数大的点,由于总共M条边,均摊下来也是根号M

                (2)代码实现

#include "bits/stdc++.h"
#define rep(i,z,n) for(int i = z;i <= n; i++)
#define per(i,n,z) for(int i = n;i >= z; i--)
#define ll long long
#define db double
#define PII pair<int,int>
#define fi first
#define se second
#define vi vector<int>
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
using namespace std;
const int N = 2e5 + 10;
vector<int>G[N];
int deg[N],cnt[N],a[N];
PII e[N];
void solve()
{
    int n,m,q;
    cin>>n>>m>>q;
    rep(i,1,m) {
        cin>>e[i].fi>>e[i].se;
        deg[e[i].fi]++,deg[e[i].se]++;
    }
    rep(i,1,m) {
        if(deg[e[i].fi]<=deg[e[i].se]) G[e[i].fi].push_back(e[i].se);
        else G[e[i].se].push_back(e[i].fi);
    }
    while(q--){
        int n;
        int ans=0;
        cin>>n;
        rep(i,1,n) {
            cin>>a[i];
            cnt[a[i]]++;
        }
        rep(i,1,n) for(auto x:G[a[i]]) ans+=cnt[x];
        rep(i,1,n) cnt[a[i]]=0;
        cout<<ans<<endl;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int T = 1;
    // cin >> T;
    while(T --) solve();
    return 0;
}

       

        I-Tokitsukaze and Musynx_2023牛客寒假算法基础集训营2 (nowcoder.com)

        (1)解题思路

                把第一个范围作为起始点位移,然后计算位移到这个区间需要的价值,用个map实现差分即可。

        (2)代码实现

#include "bits/stdc++.h"
#define rep(i,z,n) for(int i = z;i <= n; i++)
#define per(i,n,z) for(int i = n;i >= z; i--)
#define ll long long
#define db double
#define PII pair<int,int>
#define fi first
#define se second
#define vi vector<int>
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
using namespace std;
const int N = 2e5 + 10;
int X[N],V[N];
void solve()
{
    int n;
    cin>>n;
    rep(i,1,n) cin>>X[i];
    int a,b,c,d;
    cin>>a>>b>>c>>d;
    d++;
    rep(i,1,5) cin>>V[i];
    ll ans=0,res=0;
    map<int,ll> mp;
    rep(i,1,n) {
        res += V[1];
        mp[a-X[i]]+=V[2]-V[1];
        mp[b-X[i]]+=V[3]-V[2];
        mp[c-X[i]]+=V[4]-V[3];
        mp[d-X[i]]+=V[5]-V[4];
    }
    ans=res;
    for(auto x:mp) res+=x.se,ans=max(ans,res);
    cout<<ans<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int T = 1;
    cin >> T;
    while(T --) solve();
    return 0;
}

第三场

        K-永恒守候的爱恋_2023牛客寒假算法基础集训营3 (nowcoder.com)

       (1)解题思路

                根据质数分解定理,每一次新增一个质数可以增加(cnt+1)/cnt的倍率的因子数。

                由此我们可以考虑把每一个看成是一个等比数列,然后枚举n次计算n个等比数列的和即可。

        (2)代码实现

#include "bits/stdc++.h"
#define rep(i,z,n) for(int i = z;i <= n; i++)
#define per(i,n,z) for(int i = n;i >= z; i--)
#define PII pair<int,int>
#define fi first
#define se second
#define vi vector<int>
using namespace std;
using ll = long long;
const int N = 2e5 + 10;
const ll mod = 1e9+7;
ll d[N];
ll ksm(ll a,ll p)
{
	ll res=1;
	a%=mod;
	while(p){
		if(p&1) res=res*a%mod;
		p>>=1;
		a=a*a%mod;
	}
	return res;
}
void solve()
{
    int n,x;
    cin>>n;
    rep(i,1,n) {
    	cin>>x;
    	if(x>=1) d[1]+=1,d[x+1]-=1;
    }
    rep(i,1,2e5) d[i]+=d[i-1];
    ll pre=1,ans=0;
    rep(i,1,2e5) {
    	if(d[i]) {
    		ll q=(i+1ll)*ksm(i,mod-2)%mod;
    		pre=pre*q%mod;
    		ll an=pre*(ksm(q,d[i]-1)%mod+mod)%mod;
	    	ll up=pre-an*q,dw=1-q;
	    	up=(up%mod+mod)%mod,dw=(dw%mod+mod)%mod;
	    	ans=(ans+up*ksm(dw,mod-2))%mod;
	    	pre=an;
    	}
    }
    cout<<ans<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int T = 1;
    // cin >> T;
    while(T --) solve();
    return 0;
}

       I-灵魂碎片的收集_2023牛客寒假算法基础集训营3 (nowcoder.com)

        (1)解题思路

                分类讨论

                1.若n为5,答案为-1

                2.若n为1,3,7,答案为2,4,8

                3.若n为偶数,若n-1为质数,则答案为(n-1)*(n-1)

                4.若n为偶数,若n-3为质数,则答案为3*(n-1)

                5.若n为奇数,则枚举1-n中是否有两个不相同的质数相加为n-1(一定成立,根据哥德巴赫猜想可知,若n为偶数,则一定会有两个不相同的质数相加等于n)

          (2)代码实现

#include "bits/stdc++.h"
#define rep(i,z,n) for(int i = z;i <= n; i++)
#define per(i,n,z) for(int i = n;i >= z; i--)
#define PII pair<int,int>
#define fi first
#define se second
#define vi vector<int>
using namespace std;
using ll=long long;
const int N = 4e6 + 10;
bitset<N>st;
int primes[N],cnt;
unordered_map<int,int> mp;
void init()
{
	int n=2e6;
    mp[1]=2;
    mp[7]=8;
    mp[3]=4;
	for(int i=2;i<=n;i++) {
		if(!st[i]) primes[++cnt]=i;
		for(int j=1;primes[j]<=n/i;j++) {
			st[primes[j]*i]=1;
			if(i%primes[j]==0) break;
		}
	}
}
void solve()
{
    int n;
    cin>>n;
    if(mp.count(n)) {
        cout<<mp[n]<<endl;
        return;
    }
    if(n==5) {
        cout<<-1<<endl;
        return;
    }
    if(!(n&1)){
        if(!st[n-1]) {
            cout<<1ll*(n-1)*(n-1)<<endl;
            return;
        }
        else {
            cout<<(n-3)*2<<endl;
            return;
        }
    }
    else {
        n--;
        rep(i,2,n) {
            int x=i,y=n-x;
            if(x==y||y==1) continue;
            if(st[x]||st[y]) continue;
            cout<<x*y<<endl;
            return;
        }
    }
}
int main()
{
	init();
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int T = 1;
    cin >> T;
    while(T --) solve();
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值