1. 程式人生 > >【洛谷P1311】選擇客棧

【洛谷P1311】選擇客棧

被人 聽說 應該 stream cnblogs str blog spa cstring

這個題聽說二分,但是我太菜不會二分,我就會模擬做qwq,時間復雜度O(nk)

我們可以先預處理出所有花費不超過p的咖啡廳,然後預處理一下各色客棧的前綴和。

之後我們假設咖啡廳左邊及自己共有li間i色客棧,右邊有ri間i色客棧,那麽答案應該加上li*ri。但是我們發現這樣是會漏掉一種情況的,當這家咖啡廳所在的客棧作為右邊被人居住的客棧的時候,我們會漏算。因此我們需要for兩邊第一遍處理li*ri的情況,第二遍再單獨處理咖啡廳作為右端點的情況。

#include<iostream>
#include<cstring>
#include<cstdio>
using
namespace std; typedef long long lo; lo n,k,p,x,se[200020],s[200020][50],ans,wei[200020],tot; int main() { scanf("%lld%lld%lld",&n,&k,&p); for(int i=1;i<=n;i++) { scanf("%lld%lld",&se[i],&x); if(x<=p)//記錄下所有的消費小於p的咖啡廳 wei[++tot]=i; }
for(int i=1;i<=n;i++)//統計下前綴和 { for(int j=0;j<k;j++) s[i][j]+=s[i-1][j]; s[i][se[i]]++; } for(int i=1;i<=tot;i++)//先處理一般情況 for(int j=0;j<k;j++) ans+=(s[wei[i]][j]-s[wei[i-1]][j])*(s[n][j]-s[wei[i]][j]); for(int i=1;i<=tot;i++)//
再對作為右側客棧的情況進行處理 ans+=s[wei[i]-1][se[wei[i]]]-s[wei[i-1]][se[wei[i]]]; cout<<ans; }

【洛谷P1311】選擇客棧