[USACO04OPEN]The Cow Lineup
这题是被换了么,为啥感觉题解和题面讲的不是同一个东西?/qd
题意简述
给你一个值域为
Solution
双倍经验
输出方案是简单的,考虑这两题的差别就是数据范围。
先大概来康康当值域小的时候的做法。也就是上面那题。考虑 dp。
我们令
这题能获得 92pts。
现在我们考虑优化这个东西。实际上,这个
一个小问题就是我们希望这个堆能够删除某个特定的值,那就开两个堆,然后要删除一个元素就将其加入到第二个堆中,查询的时候,如果两个堆对顶相同就同时弹出即可。
Code
#include<bits/stdc++.h>
#define inf (1<<30)
#define INF (1ll<<60)
#define pb emplace_back
#define pii pair<int,int>
#define mkp make_pair
#define fi first
#define se second
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
#define per(i,j,k) for(int i=(j);i>=(k);i--)
#define pt(a) cerr<<#a<<'='<<a<<' '
#define pts(a) cerr<<#a<<'='<<a<<'\n'
#define int long long
using namespace std;
struct Heap{
priority_queue<int,vector<int>,greater<int>> q,del;
void push(int v){q.push(v);}
void pop(int v){del.push(v);}
int top(){
while(!q.empty()&&!del.empty()&&q.top()==del.top())
q.pop(),del.pop();
return q.top();
}
}q;
const int MAXN=1e5+10;
int dp[MAXN],nxt[MAXN],c[MAXN];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n,k;cin>>n>>k;
rep(i,1,n) cin>>c[i];
rep(j,1,k) nxt[j]=-1;
memset(dp,0x3f,sizeof(dp));
int cnt=0;
per(i,n,1){
if(nxt[c[i]]==-1) cnt++;
else q.pop(dp[nxt[c[i]]+1]+1);
nxt[c[i]]=i;
q.push(dp[nxt[c[i]]+1]+1);
dp[i]=(cnt==k?q.top():1);
}cout<<dp[1];
return 0;
}