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)\)。

浙公网安备 33010602011771号