zoukankan      html  css  js  c++  java
  • 5.1培训考试二

    今天小姐姐给了我们说良心很良心,说毒瘤很毒瘤的一套题(小姐姐说是可以AK的)

    老师一定刚去看了复联4

    据说这是道水题,一个set模拟就好了

    来我们看看小姐姐的标程(仅限c++11)

    #include <cstdio>
    #include <set>
    #include <algorithm>
    using namespace std;
    
    class People {
        int id, force;
        People() {}
        People(int i, int f): id(i), force(f) {}//构造函数,意思是把id赋值为i,把force赋值为f
    };
    
    bool operator <(People x, People y) {
        return x.force < y.force;
    }
    
    int n;
    set <People> s;
    
    
    int main() {
        scanf("%d", &n);
        s.insert(People(1, 1000000000));
        for (int i = 1, x, y; i <= n; ++i) {
            scanf("%d%d", &x, &y);
            auto it1 = s.upper_bound(People(x, y));//找到第一个大于当前能力的人,这里返回的是指针
            if (it1 == s.begin()) printf("%d %d
    ", x, it1->id);//如果是第一个人,就让他和超人比
            else {
                auto it3 = it1;
                auto it2 = --it3;//上面的数的前一个数的指针
                int a1 = abs(it1->force - y);//与第一个大于其的数的能力值比较
                int a2 = abs(it2->force - y);//和it2指向的数的能力值比较
                if (a2 <= a1) it1 = it2;//选取最小的(这里依旧是指针)
                printf("%d %d
    ", x, it1->id);//把那个数输出来
            }
            s.insert(People(x, y));//比较完后加入set
        }
        return 0;
    }

    bat-man:

    60pts:

    O(n^2)暴力枚举

    80pts:

    st表讲解(里面的程序没有加小姐姐的神奇输入输出,但主要部分就是里面的程序辣)

    加了小姐姐的输入输出:

    #include <cstdio>
    #include <ctime>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const int N = 1e7 + 5;
    
    long long st[1<<23][23];
    int n, m, a[N], ans[N];
    int gen, cute1, cute2;
    int number() {
        gen = (1LL * gen * cute1) ^ cute2;
        return (gen & (n - 1)) + 1;
    }
    int seach(int l,int r)
    {  int t=log((double)(r-l+1))/log(2.0);
       return max(st[l][t],st[r-(1<<t)+1][t]);
    }
    int main() {
        scanf("%d%d", &n, &m);
        scanf("%d%d%d", &gen, &cute1, &cute2);
         for (int i = 1; i <= n; ++i)//小姐姐的输入输出
            a[i] = number(); 
        for(int i=1;i<=n;i++)
          st[i][0]=a[i];
          double sx=log((double) n)/log(2.0);
        for(int j=1;j<=sx;j++)//剩下的就是st表了qwq
         { for(int i=1;(i+(1<<j))-1<=n;i++)
          {st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
          }
         }
        for (int i = 1; i <= m; ++i) {
            int l = number(), r = number();
            if (l > r) swap(l, r);
             ans[i]=seach(l,r);
        }
        int sum = 0;
        
        for (int i = 1; i <= m; ++i)
            sum = (1LL * sum * cute1 + ans[i]) % cute2;
        printf("%d
    ", sum);
    }

    100pts:

    我们使用并查集。

     小姐姐的代码(看不懂QwQ嘤~)

    #include <cstdio>
    #include <ctime>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    
    const int N = 1e7 + 5;
    
    int n, m;
    int gen, cute1, cute2;
    int number() {
        gen = (1LL * gen * cute1) ^ cute2;
        return (gen & (n - 1)) + 1;
    }
    
    
    int hd[N], nxt[N], id[N], to[N], cnt;
    int ans[N], a[N], p[N], q[N];
    
    int add(int x, int y, int i) {
        ++cnt;
        nxt[cnt] = hd[x];
        to[cnt] = y;
        id[cnt] = i;
        hd[x] = cnt;
    }
    
    
    int getfa(int x, int y) {
        int fa = x;
        for (int i = x; i; i = p[i])
            if (p[i] < y || p[i] == i) {
                fa = i;
                break;
            }
        for (int j, i = x; i != fa; i = j) {
            j = p[i], p[i] = fa;
        }
        return fa;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        scanf("%d%d%d", &gen, &cute1, &cute2);
    
        for (int i = 1; i <= n; ++i)
            a[i] = number();
        for (int i = 1; i <= m; ++i) {
            int l = number(), r = number();
            if (l > r) swap(l, r);
            add(l, r, i);
        }
        double t1;
        fprintf(stderr, "%lf
    ", t1 = (double)clock()/CLOCKS_PER_SEC);
    
        int ind = 0;
        for (int i = 1; i <= n; ++i) {
            while (ind && a[q[ind]] <= a[i]) --ind;
            if (ind) p[i] = q[ind];
            else p[i] = i;
            q[++ind] = i;
        }
    
        for (int i = n; i; --i) {
            for (int j = hd[i]; j; j = nxt[j])
                ans[id[j]] = a[getfa(to[j], i)];
        }
    
    
        fprintf(stderr, "%lf
    ", (double)clock()/CLOCKS_PER_SEC - t1);
    
        int sum = 0;
        for (int i = 1; i <= m; ++i)
            sum = (1LL * sum * cute1 + ans[i]) % cute2;
        printf("%d
    ", sum);
    }

     

    40pts:

    暴力模拟(胡说,我暴力只有10分)

    100pts:

    二分答案+check

    我们枚举一个答案t,将原来的所有的a[i]都减去t.

    那我们看有多少个区间的和等于0,如果刚好有k个,那t就是答案。

    如何看区间的和?

    既然我们二分,就是为了快,所以肯定不能O(n)暴力算是吧。

    我们使用前缀和与归并排序来进行这波操作。

    扯不下去了233

    具体的看小姐姐的代码吧

    看不懂233qwq

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <cctype>
    #include <climits>
    #include <cassert>
    #include <ctime>
    #include <iostream>
    #include <fstream>
    #include <algorithm>
    #include <functional>
    #include <string>
    
    #define x first
    #define y second
    #define MP std::make_pair
    #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
    #ifdef __linux__
    #define getchar getchar_unlocked
    #define putchar putchar_unlocked
    #endif
    #pragma GCC optimize("O3")
    
    typedef long long LL;
    typedef std::pair<int, int> Pii;
    
    const int oo = 0x3f3f3f3f;
    
    template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, true : false; }
    template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, true : false; }
    std::string procStatus()
    {
        std::ifstream t("/proc/self/status");
        return std::string(std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>());
    }
    template<typename T> T read(T &x)
    {
        int f = 1;
        char ch = getchar();
        for (; !isdigit(ch); ch = getchar())
            if (ch == '-')
                f = -1;
        for (x = 0; isdigit(ch); ch = getchar())
            x = 10 * x + ch - '0';
        return x *= f;
    }
    template<typename T> void write(T x)
    {
        if (x == 0) {
            putchar('0');
            return;
        }
        if (x < 0) {
            putchar('-');
            x = -x;
        }
        static char s[20];
        int top = 0;
        for (; x; x /= 10)
            s[++top] = x % 10 + '0';
        while (top)
            putchar(s[top--]);
    }
    
    const int MAXN = 1e5 + 5;
    
    int N;
    LL K;
    int A[MAXN];
    
    LL mergeSort(long double a[], register int n)
    {
        if (n <= 1)
            return 0;
        register int mid = n >> 1;
        register LL ret = mergeSort(a, mid) + mergeSort(a + mid, n - mid);
    
        static long double t[MAXN];
        register int p = 0, q = mid, tot = 0;
        while (p < mid || q < n) {
            if (p < mid && (q == n || a[p] <= a[q])) {
                t[tot++] = a[p++];
                ret += q - mid;
            } else
                t[tot++] = a[q++];
        }
        memcpy(a, t, sizeof(*a) * n);
        return ret;
    }
    
    bool check(register long double mid)
    {
        static long double sum[MAXN];
    
        sum[0] = 0;
        for (int i = 1; i <= N; ++i) {
            sum[i] = sum[i - 1] + A[i] - mid;
        }
    
        return mergeSort(sum, N + 1) >= K;
    }
    
    void input()
    {
        read(N); read(K);
        for (int i = 1; i <= N; ++i) {
            read(A[i]);
        }
    }
    
    void solve()
    {
        long double l = *std::min_element(A + 1, A + N + 1), r = *std::max_element(A + 1, A + N + 1);
        while (clock() < 0.9 * CLOCKS_PER_SEC) {
            long double mid = (l + r) / 2;
            (check(mid) ? r : l) = mid;
        }
        printf("%.4f
    ", (double)r);
    }
    
    int main()
    {
        input();
        solve();
    
        return 0;
    }
  • 相关阅读:
    SQL中sum(),avg()等统计结果为null的解决方法 dodo
    DRM内容数据版权加密保护技术学习(上):视频文件打包实现(转) dodo
    如何使用VS2008打开VS2010的解决方案 dodo
    winform程序读取和改写配置文件App.config元素的值 dodo
    Gamification:互联网产品的游戏化设计思路 dodo
    打包发布WinForm应用程序 dodo
    使用HttpHandler做文件过滤器,验证下载文件权限 dodo
    c# cookie使用 dodo
    Balsamiq Mockups 小技巧 dodo
    Snacktools:一套基于Web应用的富媒体编辑器 dodo
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/10813792.html
Copyright © 2011-2022 走看看