VIJOS国庆节模拟赛之繁星春水

1 P1881 闪烁的繁星

分治,维护几个结果即可。

#include <cstdio>
#include <iostream>
using namespace std;

const int maxn = 200007;
int a[maxn<<2][3];
int b[maxn];


#define LL        1
#define RR        2


void build(int l, int r, int i)
{
    a[i][0] = a[i][1] = a[i][2] = 1;
    if (l == r) return;
    else {
        int m = l+r >> 1;
        build(l, m, i<<1), build(m + 1, r, i<<1 | 1);
    }
    
}

void modify(int p, int l, int r, int i)
{
    if (l == r)    return;
    else {
        int m = l+r >> 1;
        if (p <= m) modify(p, l, m, i<<1);
        else modify(p, m+1, r, i<<1 | 1);
        
        if (b[m] != b[m+1]) {
            //printf("[%d, %d][%d, %d]
", l, m, m+1, r);
            if (a[i<<1][LL] >= m-l+1)
                a[i][LL] = m-l+1 + a[i<<1 | 1][LL];
            else a[i][LL] = a[i<<1][LL];
            if (a[i<<1 | 1][RR] >= r-m)
                a[i][RR] = r-m + a[i<<1][RR];
            else a[i][RR] = a[i<<1 | 1][RR];
            a[i][0] = max(a[i<<1][RR] + a[i<<1 | 1][LL], max(a[i<<1][0], a[i<<1][1]));
            //printf("%d 0]%d 1]%d 2]%d
", i, a[i][0], a[i][1], a[i][2]);
        } else {
            a[i][0] = max(a[i<<1][0], a[i<<1 | 1][0]);
            a[i][LL] = a[i<<1][LL];
            a[i][RR] = a[i<<1 | 1][RR];
        }
    }
    
}

int main(void)
{
    int N, Q;
    scanf("%d%d", &N, &Q);
    build(1, N, 1);
    for(int i=0; i<Q; ++i) {
        int c;
        scanf("%d", &c); b[c] ^= 1;
        modify(c, 1, N, 1);
        printf("%d
", a[1][0]);
    }
    return 0;
}

2 P1882 石阶上的砖

可以想到是贪心策略,既然要求两边依次相差1,我们索性就先减掉然后再贪心。比赛时2b的最后拍了求平均数的解答,结果测试数据没一个对的= =。

改成求中位数就AC了,正确性也是不难证明的。。。(太2b了)

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <vector>
 4 using namespace std;
 5 
 6 typedef long long LL;
 7 LL castle[2][300002];
 8 vector<LL> sorted;
 9 
10 #define abs(x) ((x)<0?-(x):(x))
11 
12 int main(void)
13 {
14     int N;
15     scanf("%d", &N);
16     for(int i=0;i<N; ++i) scanf("%I64d", &castle[0][i]);
17     for(int i=0;i<N; ++i) scanf("%I64d", &castle[1][i]);
18     
19     int mid = N>>1;
20     sorted.push_back(castle[0][mid]), sorted.push_back(castle[1][mid]);
21     for(int i=1; i+i+1<=N; ++i){
22         castle[0][mid - i] -= i, castle[1][mid - i] -= i;
23         castle[0][mid + i] -= i, castle[1][mid + i] -= i;
24         
25         sorted.push_back(castle[0][mid - i]), sorted.push_back(castle[0][mid + i]);
26         sorted.push_back(castle[1][mid - i]), sorted.push_back(castle[1][mid + i]);
27     }
28     sort(sorted.begin(), sorted.end());
29     // 求中位数 
30     int median = sorted.size() >> 1;    
31     LL ans = 0;
32     for(int i=0; i<N; ++i) {
33         ans += abs(castle[0][i] - sorted[median]);
34         ans += abs(castle[1][i] - sorted[median]);
35     }
36     printf("%I64d
", ans);
37     return 0;
38 }
原文地址:https://www.cnblogs.com/e0e1e/p/4008078.html