[hihoCoder][Offer收割]编程练习赛61

最小排列

在每个给定的数字输出前按从小到大的顺序输出所有比它小的数字

#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

int a[110000];
bool f[110000];

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n, m, x;
    memset(f, false, sizeof(f));
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        cin >> a[i];
        f[a[i]] = true;
    }
    int p = 1;
    for (int i = 0; i < m; i++) {
        for (int j = p; j < a[i]; j++) {
            if (!f[j]) {
                cout << j << endl;
            }
        }
        cout << a[i] << endl;
        p = max(p, a[i]);
        while (f[p]) p++;
    }
    for (int i = p; i <= n; i++) cout << i << endl;
    return 0;
}
View Code

最大前缀和

枚举每个前缀,选出左侧最小的k个数字和右侧最大的k个数字,枚举0~k次交换

#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

class Virtul_List {
public:
    int data[100000], pre[100000], nex[100000], head, end, sz;
    bool exist[100000];
    Virtul_List() {};
    void build(PII * a, int n) {
        for (int i = 0; i < n; i++) data[i] = a[i].first;
        head = 0, end = -1, sz = n;
        for (int i = 1; i < n; i++) pre[i] = i - 1;
        for (int i = 0; i < n; i++) nex[i] = i + 1;
        nex[n - 1] = end;
        memset(exist, true, sizeof(exist));
    }
    void insert(int x, int w) {
        int l = x, r = nex[x];
        data[sz] = w;
        nex[l] = sz, pre[sz] = l, nex[sz] = r, pre[r] = sz;
        sz++;
    }
    void erase(int x) {
        if (x == end) return;
        if (x >= sz || !exist[x]) return;
        if (x == head) {
            head = nex[x];
        } else {
            int l = pre[x], r = nex[x];
            nex[l] = r, pre[r] = l;
        }
        exist[x] = false;
    }
    int next(int x) {
        return nex[x];
    }
};
Virtul_List vl;
map<PII, int> mp;
int a[100000];
PII b[100000];

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n, k, m[4], M[4];
    cin >> n >> k;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        b[i] = make_pair(-a[i], i);
    }
    sort(b, b + n);
    for (int i = 0; i < n; i++) b[i].first *= -1;
    mp.clear();
    for (int i = 0; i < n; i++) mp[b[i]] = i;
    vl.build(b, n);
    lint ans = 0, sum = 0;
    m[0] = m[1] = m[2] = 1000000001;
    for (int i = 0; i < n; i++) {
        sum += a[i];
        vl.erase(mp[make_pair(a[i], i)]);
        ans = max(ans, sum);
        m[3] = a[i];
        sort(m, m + 4);
        lint tmp = sum;
        int head = vl.head;
        for (int i = 0; i < k; i++) {
            if (head == vl.end) continue;
            tmp = tmp - m[i] + vl.data[head];
            ans = max(ans, tmp);
            head = vl.next(head);
        }
    }
    cout << ans << endl;
    return 0;
}
View Code

质数

打出2~10^6的质数表,枚举每个质数,在l~r内枚举其倍数

#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

bool f[1100000];
int p[1100000], a[1100000], c[1100000];

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n = 0, l, r;
    cin >> l >> r;
    memset(f, true, sizeof(f));
    f[0] = f[1] = false;
    for (int i = 2; i < 1000000; i++) {
        if (f[i]) {
            p[n++] = i;
            for (int j = i + i; j < 1000000; j += i) f[j] = false;
        }
    }
    for (int i = l; i <= r; i++) a[i - l] = i;
    memset(c, 0, sizeof(c));
    for (int i = 0; i < n; i++) {
        int j = l / p[i];
        if (l % p[i] != 0) j++;
        j *= p[i];
        for (; j <= r; j += p[i]) {
            while (a[j - l] % p[i] == 0) a[j - l] /= p[i], c[j - l]++;
        }
    }
    int ans = 0;
    for (int i = l; i <= r; i++) {
        if (a[i - l] != 1) c[i - l]++;
        if (f[c[i - l]]) ans++;
    }
    cout << ans << endl;
    return 0;
}
View Code

随机排列2

每次x值在位置i出发生改变时表示此时p[i]是p[1~i]中最大的值,这件事发生的次数为n!/i

#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

inline lint pow(lint a, lint b, lint p) {
    lint rtn = 1;
    while (b) {
        if (b & 1) rtn = rtn * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return rtn;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n;
    cin >> n;
    lint frac = 1;
    for (int i = 1; i <= n; i++) frac = frac * i % 1000000007;
    lint ans = 0;
    for (int i = 1; i <= n; i++) {
        ans += (frac * pow(i, 1000000005, 1000000007)) % 1000000007;
        ans %= 1000000007;
    }
    cout << ans << endl;
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/dramstadt/p/9104066.html