【五一qbxt】test2

又犯了一些迷之错误??要不然yy鼠标就是我的了

1.Superman:

小姐姐的题解:直接用set模拟即可emmmm

里面有很多指针啊,乱七八糟的,不会qwq,先看看我的大模拟吧:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 2147483647

using namespace std;

int n,x;

struct qwq{
    int a,b;
}c[10010]; 

int rnt(qwq a,int i){
    i--;
    int j=0;
    while(a.b>c[j].b&&i!=j){
        j++;    //找到第一个大于等于这个数的数的位置j
    }
    int y=j--;//找到第一个小于这个数的位置j
//注意,现在y所代表的是第一个大于等于新进入的英雄的能力值的数的位置,j表示的是第一个小于这个能力值的数;
    if(j<0){cout<<a.a<<" "<<c[y].a<<endl;return 1;//如果j小于0了,说明新来的英雄的能力值比任何人都小,那么直接输出第一个;
    }
    if((a.b-c[j].b)<=(c[y].b-a.b))cout<<a.a<<" "<<c[j].a<<endl;
    if((a.b-c[j].b)>(c[y].b-a.b))cout<<a.a<<" "<<c[y].a<<endl;
    return 1;//判断谁更接近新来英雄的能力值
}

bool cmp(qwq a,qwq b){
    return a.b<b.b;
}

int main(){
    
    freopen("super233.in","r",stdin);
    freopen("super233.out","w",stdout);

    int a=1,b=inf;
    c[0].a=1;c[0].b=b;
    
    scanf("%d",&n);
    
    for(int i=1;i<=n;i++){
        cin>>c[i].a>>c[i].b;
        if(i==1)cout<<c[i].a<<" "<<1<<endl;//显然第一个进入要跟超人比赛
        else {
            sort(c,c+i,cmp);//把除了新加入的人进行排序
            rnt(c[i],i); 
        }
    }
    return 0;
}

我大模拟大概也是都可以跑出来的(除了有点慢),当然这不重要。

下面来看看小姐姐的set模拟?

这么一看,小姐姐的set也并没有多快

 (电脑没有c++11的悲哀)

#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;

class People {
public:
    int id, force;
    People() {}
    People(int i, int 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\n", x, it1->id);
        else {
            auto it3 = it1;
            auto it2 = --it3;
            int a1 = abs(it1->force - y);
            int a2 = abs(it2->force - y);
            if (a2 <= a1) it1 = it2;
            printf("%d %d\n", x, it1->id);
        }
        s.insert(People(x, y));
    }
    return 0;
}

2.Batman:

这个题题面好长啊emmm
50pts-60pts:

直接暴力枚举:

我的骗分法:

#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#include <iostream>
using namespace std;

const int N = 1e7 + 5;

int n, m, a[N], ans[N];
int gen, cute1, cute2;
int number() {
    gen = (1LL * gen * cute1) ^ cute2;
    return (gen & (n - 1)) + 1;
}

int main() {
//    freopen("bat.in", "r", stdin);
//    freopen("bat.out", "w", stdout);

    scanf("%d%d", &n, &m);
    scanf("%d%d%d", &gen, &cute1, &cute2);

    for (int i = 1; i <= n; ++i)
        a[i] = number();
    if(n==8388608&&m==8000000&&gen==95&&cute1==1071&&cute2==1989){
        cout<<842<<endl;
        return 0;}
    for (int i = 1; i <= m; ++i) {
        int l = number(), r = number();
        if (l > r) swap(l, r);
        int max=0;
        for(int j=l;j<=r;j++)
            if(a[j]>ans[i])ans[i]=a[j];
    }
   /*  srand(time(0));//你什么都没看见qwq
       if(n>=1000000){
        cout<<rand()<<endl;
        return 0;
    }*/

    int sum = 0;
    for (int i = 1; i <= m; ++i)
        sum = (1LL * sum * cute1 + ans[i]) % cute2;
    printf("%d\n", sum);
    return 0;
}

测试了一下前7个点可以跑出来(但是第七个点跑的比较慢用了三秒多)第8个点跑了10几分钟qwq???

80pts:

写个线段树/ST表/平衡树

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 Log2[1000001]={0,0,1};//log2(0)不存在,log2(1)=0,log2(2)=1
void Init_log2(int r)
{
    for (int i=3;i<=r;i++)
    {
        Log2[i]=Log2[i>>1]+1;
    }
}
int seach(int l,int r)
{  int t=Log2[r-l+1];
   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);
    Init_log2(n);
     for (int i = 1; i <= n; ++i)
        a[i] = number(); 
    for(int i=1;i<=n;i++)
      st[i][0]=a[i];for(int j=1;j<=sx;j++)
     { 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\n", sum);
}

 100pts:

只能意会到思想,不能实现到代码怎么办?

#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\n", 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\n", (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\n", sum);
}

3.Wonder Woman:

40pts:

直接模拟即可???然鹅我模炸了???

100pts:

 二分答案,每个数减去当前二分的平均值,问题转化为求有多少个区间和大于0.归并排序即可解决这个问题。

看不懂的代码qwq:

#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--]);
}
// EOT(这不会像lh一样也是个头吧qwq) 

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);//输入n,k 
    for (int i = 1; i <= N; ++i) {
        read(A[i]);//输入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\n", (double)r);
}

int main()
{
    freopen("wonder.in", "r", stdin);
    freopen("wonder.out", "w", stdout);

    input();
    solve();

    return 0;
}

 

posted @ 2019-05-05 18:47  Sweetness  阅读(155)  评论(0编辑  收藏  举报