Solution to a problem P2564 [[SCOI2009] birthday gift]

Topic Link

Solution [SCOI2009] birthday gift

Title effect: \ (X \) a number of different types of beads on the whole point of the shaft, seeking a shortest length \ (ANS \) , so long as there is a \ (ANS \) section contains all kinds of beads

Analysis:
First, we answer a monotone , if short interval to meet the requirements that must also meet the long interval

So we can consider half

About half of the \ (Check \) may be implemented in a similar manner monotone queue (i.e. emulated feet)

We maintain two pointers \ (i \) , \ (J \) to move to the right each time step \ (J \) , followed by the \ (i \) has been to the right, until \ (i \) , \ ( j \) interval within the meaning of the beads formed to meet the requirements to safeguard what kinds of colors in the process

Complexity \ (O (nlog \ max \ {POS \}) \) , \ (POS \) to position beads

Code:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;
const int maxn = 1e6 + 100;
inline int read(){
    int x = 0;char c = getchar();
    while(!isdigit(c))c = getchar();
    while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    return x;
}
struct Node{
    int pos,opt;
    bool operator < (const Node &rhs)const{return pos < rhs.pos;}
}val[maxn];
int cnt[64],q[maxn],tot,now_col,n,k;
inline void ins(int x){if(!(cnt[x]++))now_col++;}
inline void del(int x){if(!(--cnt[x]))now_col--;}
inline bool check(int len){
    now_col = q[0] = 0;memset(cnt,0,sizeof(cnt));
    int head = 0,tail = 0;
    for(int i = 1;i <= tot;i++){
        while(head <= tail && val[q[head]].pos < val[i].pos - len)del(val[q[head++]].opt);//右移i
        ins(val[i].opt);
        q[++tail] = i;//右移j
        if(now_col == k)return true;
    }
    return false;
}
int main(){
    n = read(),k = read();
    for(int i = 1;i <= k;i++){
        int x = read();
        while(x--)val[++tot] = Node{read(),i};
    }
    sort(val + 1,val + 1 + tot);
    int l = 0,r = 0x7fffffff - 1,ans = -1;
    while(l <= r){
        int mid = (l + r) >> 1;
        if(check(mid))ans = mid,r = mid - 1;
        else l = mid + 1;
    }
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/colazcy/p/11518547.html