1. 程式人生 > >BZOJ4893: 項鏈分贓 && BZOJ4895: 項鏈分贓(增強版)

BZOJ4893: 項鏈分贓 && BZOJ4895: 項鏈分贓(增強版)

拓撲 clas 打開 n) while bzoj solution include main

Solution

神仙題.jpg

切一刀簡單啊,維護一個前綴和。

切兩刀簡單啊,拿個隊列維護中間那一段。

切三刀,這tm什麽毒瘤題。

於是打開題解:“保證不會答案不會超過寶石種類”。

orz神仙結論。

於是去研究了一下證明,但是看不懂拓撲學...

可以看一下3Blue1Brown的這個視頻

出題人的證明

出題人大概是看了這個視頻後出了這題?

這兩題是一樣的。第二題直接輸出m就行了。

知道結論後瞎寫就行

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define N 100010
int cnt[3], sum[N][3];
int n, a[N];

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
        sum[i][0] = sum[i - 1][0];
        sum[i][1] = sum[i - 1][1];
        sum[i][2] = sum[i - 1][2];
        sum[i][a[i]]++;
    }
    for(int i = 1; i <= n; ++i) {
        if(sum[i][0] * 2 == sum[n][0] 
        && sum[i][1] * 2 == sum[n][1] 
        && sum[i][2] * 2 == sum[n][2])
            {puts("1"); return 0;}
    }
    int l = 1;
    for(int i = 1; i <= n; ++i) {
        cnt[a[i]]++;
        for(int j = 0; j < 3; ++j) {
            while(l <= i && cnt[j] * 2 > sum[n][j]) cnt[a[l]]--, ++l;
        }
        if(cnt[0] * 2 == sum[n][0] 
         && cnt[1] * 2 == sum[n][1] 
         && cnt[2] * 2 == sum[n][2])
         {puts("2"); return 0;}
    }
    puts("3");
}
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define N 100010

int n, m;
int main() {
    scanf("%d%d", &n, &m);
    printf("%d\n", m);
}

BZOJ4893: 項鏈分贓 && BZOJ4895: 項鏈分贓(增強版)