Educational Codeforces Round 89 (Rated for Div. 2)(A 三分 D 数论,E 思维)

题目链接

最近综合实训花了一大堆时间,都没怎么打比赛和写题解了。

A. Shovels and Swords

题目:四个公式2x+y<=a   x+2y<=b  x>=0 y>=0  求最大的 x+y

做法:简单的三分

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

inline ll read()
{
	ll x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}
ll a,b;
ll cal(ll y)
{
    ll x=min(b-2*y,(a-y)/2);
    //if(x<0||y<0) return 0;
    return x+y;
}
int main()
{
    int _=read();while(_--){
        a=read(),b=read();
        if(a==0||b==0){puts("0");continue;}
        if(a>b) swap(a,b);

        ll l=0,r=min(a,b/2);
        while(l+10<=r){
            ll m1=l+r>>1;
            ll m2=m1+r>>1;
            if(cal(m2)>=cal(m1)) l=m1+1;
            else r=m2-1;
        }
        ll ans=0;
        for(ll i=l;i<=r;++i){
            ans=max(ans,cal(i));
        }

        printf("%lld\n",ans);
    }
}

D. Two Divisors

题目:给你n个数,求每个的所有因子数中取两个 d1、d2  使得gcd(d1+d2,a[i])==1

做法:参考来自博客

妙。。数论  知识还是太薄弱了。。

那么 套一个线性筛就可以了。

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10,M=1e7+10;
int prime[M],vs[M],len,mi[M];
int n,ans[3][N],a[N];
void init()
{
    for(int i=2;i<M;++i){
        if(!vs[i]){
            prime[++len]=i;
            //vs[i]=1;
        }
        for(int j=1;j<=len&&i*prime[j]<M;++j){
            vs[i*prime[j]]=prime[j];
            if(i%prime[j]==0) break;
        }
    }
}
int main()
{
    init();
    scanf("%d",&n);
    for(int i=1;i<=n;++i) {
        scanf("%d",&a[i]);
        ans[1][i]=ans[2][i]=-1;
    }

    for(int i=1;i<=n;++i){
        if(!vs[a[i]]) continue;
        int d=vs[a[i]],now=1;
        while(a[i]%d==0) a[i]/=d,now=now*d;
        if(a[i]==1) continue;
        ans[1][i]=now;
        ans[2][i]=a[i];

    }
    for(int i=1;i<=n;++i) printf("%d ",ans[1][i]);
    puts("");
    for(int i=1;i<=n;++i) printf("%d ",ans[2][i]);
}

E. Two Arrays

做法参考来自:博客

没怎么打比赛,怎么思维也跟不上了。

#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
 
const int mod = 998244353;
 
 
int mult(int a, int b) {
    return (1LL * a * b) % mod;
}
 
 
int n, m;
const int maxN = 2e5 + 10;
int a[maxN];
int b[maxN];
int suf[maxN];
int cnt[maxN];
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= m; i++) {
        cin >> b[i];
    }
    suf[n + 1] = 1e9 + 10;
    for (int i = n; i >= 1; i--) {
        suf[i] = min(suf[i + 1], a[i]);
    }
    if (suf[1] != b[1]) {
        cout << 0;
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        int p = suf[i];
        int pos = lower_bound(b + 1, b + m + 1, p) - b;
        if (1 <= pos && pos <= m && b[pos] == p) cnt[pos]++;
    }
    int ans = 1;
	cout<<endl;
    for (int i = 2; i <= m; i++) {
        ans = mult(ans, cnt[i]);
    }
    cout << ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/106728772