Day 23 - 模拟赛

百万富翁的第二次实验

题目描述

马克吐温有一本非常著名的小说《百万英镑》,这本小说中主角最后归还了百万英镑给两位富翁。但结果就是两位富翁依然有无穷的问题需要进行社会实验,于是,他们打算进行第二次社会实验。那就是不同财富值的人在一场舞会上会发生什么事情。为了满足自己的好奇,百万富翁们邀请了全伦敦所有人来自己的舞会。舞会开始后他们就后悔了,因为来的人太多了,而且很多人的财富都相同,统计起来太费事了。所以百万富翁们找到你,希望你根据来舞会的时间,找出在一段时间内,来舞会的所有人财富值都互不相同的人数。

输入格式

第一行输入一个 \(n\) 表示有 \(n\) 个人参与舞会。

按照时间顺序输入 \(n\) 个人的财富值。

输出格式

输出在一段时间内参加舞会的所有人财富值都互不相同的人数的最大值。

\(\text{input1}\)

7
2 3 4 5 5 6 7

\(\text{output1}\)

4

数据范围

对于 \(100\%\) 的数据保证:每个人的财富值不超过 \(10^{11}\)\(0 \le n \le 10^6\)

#include<iostream>
#include<cmath>
#include<map>
using namespace std;
#define MAXN 1000005

long long n, a[MAXN], ans = 0;
map<long long, int> mp;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    long long l = 1, r = 1;
    while(r <= n) {
        if(!mp[a[r]]) mp[a[r]] ++;
        else {
            mp[a[r]] ++;
            while(a[l] != a[r]) mp[a[l]] --, l ++;
            mp[a[l]] --, l ++;
        }
        ans = max(ans, r - l + 1); r ++;
    }
    cout << ans << "\n";
    return 0;
}

magic

题目描述

输入格式

输出格式

\(\text{input1}\)

7 1
1 6 5 3 2 8 9
4 37

\(\text{output1}\)

2

样例解释

数据范围

\(\text{UpDate}\)\(p_i\) 范围更改为 \(1 \le p_i \le 10^8\)

#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 500005

long long n, m, a[MAXN], ap[MAXN], ar[MAXN], aq[MAXN], p, q;

bool cmp(long long x, long long y) { return x > y; }

long long check(long long mid) { return a[1] * p * mid - ar[mid] * p - aq[mid]; }

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    sort(a + 1, a + n + 1, cmp);
    for(int i = 1; i <= n; i ++) 
        ar[i] = ar[i - 1] + a[1] - a[i], aq[i] = aq[i - 1] + (i - 1) * a[i];
    while(m --) {
        cin >> p >> q;
        long long l = 1, r = p, ans = -1; 
        while(l <= r) {
            long long mid = (l + r) >> 1;
            if(check(mid) >= q) ans = mid, r = mid - 1;
            else l = mid + 1;
        }
        cout << ans << "\n";
    }
    return 0;
}

统计区间

题目描述

有一个长度为 \(n\) 的数列 \(\{a_i\}\)\(a_i \in [1, n]\) 中,现在要统计区间中出现的数都恰好出现 \(2\) 次的区间数。

输入格式

第一行一个整数 \(n\)

第二行 \(n\) 个整数表示 \(a_i\)

输出格式

一行一个整数,表示满足条件的区间数.

\(\text{input1}\)

7
5 3 5 5 4 4 3

\(\text{output1}\)

4

数据范围

对于 \(30\%\) 的数据保证:\(1 \le n \le 10^3\)

对于 \(100\%\) 的数据保证:\(1 \le n \le 10^6\)

#include<iostream>
using namespace std;
#define MAXN 1005

long long n, a[MAXN], cnt[MAXN][MAXN], mp[MAXN], ans = 0;

int main() {
    ios::sync_with_stdio(0); 
    cin.tie(0); cout.tie(0);
	cin >> n; 
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) 
        cnt[i][j] = cnt[i - 1][j] + (a[i] == j);
    for(int l = 1; l <= n; l ++) 
        for(int r = l + 1; r <= n; r += 2) {
            bool f = true;
            for(int i = l; i <= r; i ++) 
                if(cnt[r][a[i]] - cnt[l - 1][a[i]] != 2) { f = false; break; }
            ans += f;
        }
    cout << ans << "\n";
    return 0;
}

柱形图

题目描述

输入格式

输出格式

\(\text{input1}\)

5
5 3
4 4
2 1
3 2
1 5

\(\text{output1}\)

24

\(\text{input2}\)

6
3 1
2 1
2 2
2 3
1 1
2 2

\(\text{output2}\)

8

\(\text{input3}\)

5
15 19
5 6
1 13
3 7
1 2

\(\text{output3}\)

285

样例解释

样例 \(1\) 解释:见题目描述中的图。

数据范围

本题采用捆绑测试。

#include<iostream>
#include<cmath>
using namespace std;
#define MAXN 200005

long long n, a[MAXN][18], b[MAXN][18], lg[MAXN] = { -1 }, ans = 0;

long long query1(long long l, long long r) {
    long long len = lg[r - l + 1];
    long long ans = min(a[l][len], a[r - (1 << (len)) + 1][len]);
    return ans;
}

long long query2(long long l, long long r) {
    long long len = lg[r - l + 1];
    long long ans = min(b[l][len], b[r - (1 << (len)) + 1][len]);
    return ans;
}

int main() {
    ios::sync_with_stdio(0); 
    cin.tie(0); cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++) { cin >> a[i][0] >> b[i][0]; lg[i] = lg[i / 2] + 1; }
    for(int i = 1; i <= lg[n]; i ++) for(int j = 1; j + (1 << i) - 1 <= n; j ++) 
        a[j][i] = min(a[j][i - 1], a[j + (1 << (i - 1))][i - 1]), 
        b[j][i] = min(b[j][i - 1], b[j + (1 << (i - 1))][i - 1]);
    for(int l = 1; l <= n; l ++) for(int r = l; r <= n; r ++) 
        ans = max(ans, (r - l + 1) * query1(l, r) * query2(l, r));
    cout << ans << "\n";
    return 0;
}

\[100 + 100 + 30 + 20 = 250 \]

posted @ 2024-07-30 13:34  So_noSlack  阅读(33)  评论(0编辑  收藏  举报