洛谷P1296 奶牛的耳語
阿新 • • 發佈:2018-11-07
隨機跳到的一道題,雖然確實挺水但是也不至於是紅題吧qwq,可能是因為資料過水導致一大片 暴力過了所以拉低了評分,雖然以這道題的資料範圍 應該被卡掉的。
簡述題意:給定一個序列和一個數 ,求無序數對 的個數,滿足 。
思路:先將給定的序列排序,然後放入一個佇列中,維護與隊首距離 的數是哪些。當我們要加入一個數的時候,先將當前佇列中與新加入的數距離過遠的數出隊,同時更新答案,然後將新的數加入隊尾。因為我們已經將序列排好序了,所以需要出隊的數都在隊首,直接判斷即可。
考慮資料出隊時如何更新答案。我們佇列裡記錄的是比隊首大的、符合要求的數(一開始從小到大排序的話),因此答案只需要加上當前佇列裡的元素數量即可(隊首要去掉)。那麼比隊首小的符合要求的數會漏掉嗎?其實並不會,因為 和 是相同的,所以這部分已經在之前計算過了。
這樣做的複雜度為 ,過此題無壓力
最後,別被樣例坑了,輸入的資料是無序的,要記得排序(我就是這樣在一道紅題WA了兩次的QAQ,真的是天下最弱了)
貼程式碼
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100010;
int n,m,a[N],q[N],fp=1,rp;
long long ans;
int main()
{
scanf("%d%d",&n,&m);ans=0;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+n+1);//千萬別忘了排序!!!
for(int i=1;i<=n;i++)
{
while(fp<=rp&&q[fp]+m<a[i])ans=ans+rp-fp,fp++;//將不合要求的隊首出隊,同時更新答案
q[++rp]=a[i];//將當前數入隊
}
int t=rp-fp+1;ans=ans+(long long)t*(t-1)/2;//最後佇列裡會剩下一些數,別忘了處理
printf("%lld\n",ans);return 0;
}