2020.1.14(第二场)

2020.1.14(第二场)

问题 C: 小奇学数论

时间限制: 1 Sec  内存限制: 128 MB

题目描述
小奇在数论课上学习了素数判定算法,但它不满⾜于此!
求小于等于n的素数个数。
输入
输⼊1个数字n。
输出
输出1个整数,表示答案。
样例输入 Copy
10

 

样例输出 Copy
4

 

提示
对于20%的数据,1≤n≤10 4
对于40%的数据,1≤n≤10 6
对于60%的数据,1≤n≤10 7
对于80%的数据,1≤n≤10 8
对于100%的数据,1≤n≤10 11
数论题,求的是小于n的素数个数。
这个代码复杂度为O(n^3/4)
网上还有一个板子是O(n^2/3)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define rop(i,a,b) for(int i=(a);i<(b);i++)
 
using namespace std;
typedef long long ll;
const int maxn=4e5+10;
ll phi[maxn/10][105], prime[maxn], pre[maxn];
int x;
bool vis[maxn];
unordered_map<ll,ll>mp;
void init(){
    rop(i,2,maxn)
    {
        if(!vis[i]) {
            prime[x++] = i;
            for (int j = 2; j * i < maxn; j++) {
                vis[i * j] = true;
            }
            pre[i]=pre[i-1]+1;
            continue;
        }
        pre[i]=pre[i-1];
    }
 
    rep(i,0,maxn/10-5){
        phi[i][0] = (ll)i;
        rep(j,1,100){
            phi[i][j] = phi[i][j-1] - phi[i/prime[j-1]][j-1];
        }
    }
}
 
ll mpphi(ll m, ll n){
    if(n==0) return m;
    if(prime[n - 1] >= m) return 1;
    if(m<=maxn/10-5 && n<=100) return phi[m][n];
    return mpphi(m, n-1) - mpphi(m/prime[n-1], n-1);
}
 
ll get_ans(ll x){
    if(x < (ll)maxn) return pre[x];
    if(mp.count(x))
        return mp[x];
    ll y = (int)cbrt(x*1.0);
    ll n = pre[y];
    ll ans = mpphi(x, n) + n -1;
    for(ll i=n; prime[i]*prime[i]<=x; i++) ans = ans - get_ans(x/prime[i])+get_ans(prime[i])-1;
    return mp[x]=ans;
}
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    init();
    ll n;
    cin>>n;
    ll anss = get_ans(n);
    cout<<anss<<endl;
    return 0;
}

 

#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define rop(i,a,b) for(int i=(a);i<(b);i++)

using namespace std;

typedef long long ll;
const int maxn = 5e6+10;

bool vis[maxn];
int prime[maxn], pi[maxn];
int x;
void oulasai(int n)
{
    rep (i,2,n)
    {
        if(!vis[i]) prime[x++]=i;
       rop (j,0,x)
        {
            if(i*prime[j]>n) break;
            vis[i*prime[j]]=true;
            if(i%prime[j]==0) break;
        }
    }
}

const int M = 7;
const int PM = 2 * 3 * 5 * 7 * 11 * 13 * 17;
int phi[PM + 1][M + 1], sz[M + 1];

void init(){
    oulasai (maxn);
    sz[0] = 1;
    rep (i,0,PM)  phi[i][0] = i;
    rep (i,1,M){
        sz[i] = prime[i] * sz[i - 1];
        rep (j,1,M) phi[j][i] = phi[j][i - 1] - phi[j / prime[i]][i - 1];
    }
}

int sqrt2(ll x)
{
    ll r = (ll)sqrt(x - 0.1);
    while(r * r <= x)   ++r;
    return int(r - 1);
}
int sqrt3(ll x)
{
    ll r = (ll)cbrt(x - 0.1);
    while(r * r * r <= x)   ++r;
    return int(r - 1);
}
ll getphi(ll x, int s)
{
    if(s == 0)  return x;
    if(s <= M)  return phi[x % sz[s]][s] + (x / sz[s]) * phi[sz[s]][s];
    if(x <= prime[s]*prime[s])   return pi[x] - s + 1;
    if(x <= prime[s]*prime[s]*prime[s] && x < maxn)
    {
        int s2x = pi[sqrt2(x)];
        ll ans = pi[x] - (s2x + s - 2) * (s2x - s + 1) / 2;
        rep (i,s+1,s2x) ans += pi[x / prime[i]];
        return ans;
    }
    return getphi(x, s - 1) - getphi(x / prime[s], s - 1);
}
ll getpi(ll x)
{
    if(x < maxn)   return pi[x];
    ll ans = getphi(x, pi[sqrt3(x)]) + pi[sqrt3(x)] - 1;
    for(int i = pi[sqrt3(x)] + 1, ed = pi[sqrt2(x)]; i <= ed; ++i) ans -= getpi(x / prime[i]) - i + 1;
    return ans;
}
ll lehmer_pi(ll x)
{
    if(x < maxn)   return pi[x];
    int a = (int)lehmer_pi(sqrt2(sqrt2(x)));
    int b = (int)lehmer_pi(sqrt2(x));
    int c = (int)lehmer_pi(sqrt3(x));
    ll sum = getphi(x, a) +(ll)(b + a - 2) * (b - a + 1) / 2;
    for (int i = a + 1; i <= b; i++)
    {
        ll w = x / prime[i];
        sum -= lehmer_pi(w);
        if (i > c) continue;
        ll lim = lehmer_pi(sqrt2(w));
        for (int j = i; j <= lim; j++) sum -= lehmer_pi(w / prime[j]) - (j - 1);
    }
    return sum;
}
int main(){
    init();
    ll n;
    while(~scanf("%lld",&n)){
        printf("%lld\n",lehmer_pi(n));
    }
    return 0;
}
题目描述
Farmer John’s cows have recently become fans of playing a simple number game called “FizzBuzz”. The rules of the game are simple: standing in a circle, the cows sequentially count upward from one, each cow saying a single number when it is her turn. If a cow ever reaches a multiple of 3, however, she should say “Fizz” instead of that number. If a cow reaches a multiple of 5, she should say “Buzz” instead of that number. If a cow reaches a multiple of 15, she should say “FizzBuzz” instead of that number. A transcript of the first part of a game is therefore:
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16

Having a slightly more limited vocabulary, the version of FizzBuzz played by the cows involves saying “Moo” instead of Fizz, Buzz, and FizzBuzz. The beginning of the cow version of the game is therefore

1, 2, Moo, 4, Moo, Moo, 7, 8, Moo, Moo, 11, Moo, 13, 14, Moo, 16

Given N (1≤N≤109), please determine the Nth number spoken in this game.

SCORING
Test cases 2-5 satisfy N≤106.

输入
The input consists of a single integer, N.
输出
Please print out the Nth number spoken during the game.
样例输入 Copy
4

 

样例输出 Copy
7

 

提示
The 4th number spoken is 7. The first 4 numbers spoken are 1, 2, 4, 7, since we skip over any time a cow says “Moo”.
签到题。
#include <bits/stdc++.h>
 
using namespace std;
int a[9] = {0,1,2,4,7,8,11,13,14};
int work(int n) {
    int x = n%8;
    int ans = 0;
    if(x==0) {
        x+=8;
        ans-=15;
    }
    ans += a[x];
    ans+=n/8*15;
    return ans;
}
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    cout<<work(n)<<endl;
    return 0;
}

 

 

问题 A: 小奇采药

时间限制: 1 Sec  内存限制: 128 MB

题目描述
小奇是只天资聪颖的喵,他的梦想是成为世界上最伟⼤的医师。
为此,他想拜喵星球最有威望的医师为师。
医师为了判断他的资质,给他出了⼀个难题。
医师把他带到⼀个到处都是草药的⼭洞里对他说:“小奇,这个⼭洞里有⼀些不同的草药,采每⼀株都需要⼀些时间,每⼀株也有它自身的价值。
我会给你⼀段时间,在这段时间里,你可以采到⼀些草药。
如果你是⼀只聪明的喵,你应该可以让采到的草药的总价值最⼤。”
输入
第R⾏包括R个整数h,表示数据组数。
对于每组数据,第R⾏包括k个整数,M,K,表示草药的数目和能用于采药的时间。
接下来M⾏,每⾏两个整数ti,vi。
保证m,ti,vi在限制范围内均匀随机⽣成。
输出
输出h⾏,每⾏R个数字,表示每组数据答案。
样例输入 Copy
1
3 70
71 100
69 1
1 2

 

 

样例输出 Copy
3

 

提示
对于30%数据,1≤n≤20,1≤m,vi,ti≤10 4
对于60%数据,1≤n≤100,1≤m,vi,ti≤10 5
对于100%数据,1≤T≤10,1≤n≤150,1≤m,vi,ti≤10 9
剪枝。
这个搜索不擅长啊。
#pragma GCC optimize(3, "Ofast", "inline")
 
#include <bits/stdc++.h>
 
#define rep(i, a, b) for(int i=(a);i<=(b);i++)
#define per(i, a, b) for(int i=(a);i>=(b);i--)
 
const int maxn = 222;
typedef long long ll;
using namespace std;
struct node {
    ll v, w;
} e[maxn];
ll t, n, m, ans, sv[maxn], sw[maxn];
 
bool cmp(node A, node B) {
    return A.v > B.v;
}
 
void dfs(ll p, ll mm, ll vv) {
    ans = max(ans, vv);
    if (p > n)return;
    if (mm + e[n].v > m)return;
    if (vv + sw[p] <= ans)return;
    if (mm + sv[p] <= m) {
        ans = max(ans, vv + sw[p]);
        return;
    }
 
    if (mm + e[p].v <= m) {
        dfs(p + 1, mm + e[p].v, vv + e[p].w);
    }
    dfs(p + 1, mm, vv);
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> t;
    while (t--) {
        ans = 0;
        cin >> n >> m;
        rep(i, 1, n) {
            cin >> e[i].v >> e[i].w;
        }
        sort(e + 1, e + 1 + n, cmp);
        per(i, n, 1) {
            sv[i] = sv[i + 1] + e[i].v;
            sw[i] = sw[i + 1] + e[i].w;
        }
        dfs(1, 0, 0);
        cout << ans << endl;
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值