Luogu8267 solution

Problem

link->https://www.luogu.com.cn/problem/P8267

Solution

约定的数据分别为 \(opt_i,p_i\)

\(f_{0,x}\)\(opt_i=\texttt{L}\)\(x\le p_i\)\(i\) 的数量。

\(f_{1,x}\)\(opt_i=\texttt{G}\)\(x\ge p_i\)\(i\) 的数量。

容易发现,将奶牛放在 \(x\) 号点的说真话的奶牛数量为 \(f_{0,x}+f_{1,x}\),则说谎话的奶牛个数为 \(n-(f_{0,x}+f_{1,x})\)

\(a_{0,x}\) 表示 \(opt_i=\texttt{L}\)\(p_i=x\)\(i\) 的数量。

\(a_{1,x}\) 表示 \(opt_i=\texttt{G}\)\(p_i=x\)\(i\) 的数量。

\(f_{0,x}=\sum\limits_{i=x}^{\max\limits_{k=1}^n\{p_k\}}a_{0,x}\)\(f_{1,x}=\sum\limits_{i=0}^{x}a_{1,x}\)

上述二式可以使用前缀和(后缀和)求之。

不过,值的注意的一点是 \(p_i\le10^9\),这样子数组是肯定存不下的,不过,我们可以使用离散化这一技巧将所有 \(p_i\) 的值都转换到 \(1\)\(n\) 之间。这里不作过多介绍。

Code

#include<bits/stdc++.h>
#define pd push_back
#define pb pop_back
#define mk make_pair
//#define int long long
#define PII pair<int,int>
#define _for(a,b,c) for(int a=b;a<=c;a++)
#define _rep(a,b,c) for(int a=b;a>=c;a--)
using namespace std;
template <typename T> inline void read(T& x) {
	x=0; T f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch&15); ch=getchar(); }
	x=x*f;
	return;
}
template <typename T,typename ...Arg> inline void read(T& x,Arg& ...arg){
	read(x); read(arg...);
}
int power(int a,int b) {
	int ans=1;
	do {
		if(b&1) ans*=a; a*=a;
	} while(b>>=1);
	return ans;
}
const int N=1e3+5;
int a[N],t[N],sum0[N],sum1[N],n,ans,len;
char opt[N];
signed main() {
	read(n);
	_for(i,1,n)
		cin>>opt[i],read(a[i]),t[i]=a[i];
	sort(t+1,t+n+1);
	len=unique(t+1,t+n+1)-(t+1);
	_for(i,1,n) {
		int x=lower_bound(t+1,t+len+1,a[i])-t;
		if(opt[i]=='L')
			++sum0[x];
		else
			++sum1[x];
	}
	_for(i,1,len) sum1[i]+=sum1[i-1];
	_rep(i,len,1) sum0[i]+=sum0[i+1];
	_for(i,1,len)
		ans=max(ans,sum0[i]+sum1[i]);
	printf("%d",n-ans);
	return 1;
}

时间复杂度 \(\Theta(n\log{n})\),瓶颈在于排序。

当然,也可以使用哈希,平均时间复杂度 \(\Theta(n)\)

posted @ 2022-08-01 14:02  lsj2009  阅读(21)  评论(0)    收藏  举报