題目描述
給出1~n的乙個排列,統計該排列有多少個長度為奇數的連續子串行的中位數是b。中位數是指把所有元素從小到大排列後,位於中間的數。
輸入輸出格式
輸入格式:
第一行為兩個正整數n和b,第二行為1~n的排列。
【資料規模】
對於30%的資料中,滿足n≤100;
對於60%的資料中,滿足n≤1000;
對於100%的資料中,滿足n≤100000,1≤b≤n。
輸出格式:
輸出乙個整數,即中位數為b的連續子串行個數。
輸入輸出樣例
輸入樣例#1:
7 4
5 7 2 4 3 1 6
輸出樣例#1:
4題解:一道思路題。我一開始的思路是利用字首和,維護兩個字首和陣列,maxx[i]和minn[i],分別表示1到i這個點之間一共有多少比b大的數和多少比b小的數。那i~j之間比b大的數就可以用ma
xx[j
]−ma
xx[i
−1] 得到。最後列舉區間,複雜度是o(
n/4)
。這樣只能過8個點。
正解:記錄下b的位置k,第一次迴圈從k+1到n迴圈,到該數大於b時,f[
i]=f
[i−1
]+1 ,反之f[
i]=f
[i−1
]−1 ,如果f[
i]==0
則ans
++,然後用乙個陣列p記錄p[
f[i]
]++ ,表示記錄該數出現了多少次。
然後從k-1到1迴圈,同樣用f[i]記錄。然後an
s+=p
[f[i
]],f陣列含義就是遇到比b大的數就+1,遇到小的數就-1,那麼如果b的左右兩邊出現同乙個f[i],那麼說明這兩個位置之間比b大的數的個數等於比b小的數的個數,那麼直接更新答案。複雜度是o(
n).
注意,因為c++陣列下標不為負數,所以開陣列是把所有下標統一加上100000,保證下標為正,同時注意陣列大小也要相應增加100000。
orz
#include
#include
#define s 100000
using
namespace
std;
int a[200006],k,ans=0,n;
int b,minn[200006],maxx[200006],p[200006],f[200006];
int get()
while (c>='0'&&c<='9')
return x*z;
}void work()
else
if (a[i]1]+1;maxx[i]=maxx[i-1];}
else
if (a[i]==b)
}}void love()
}}void distance()
else
p[f[i]]++;
if (f[i]==s)
ans++;
}for (i=k-1;i>=1;i--)
else
ans+=p[s+s-f[i]];
if (f[i]==s)
ans++;
}printf("%d",ans+1);
}int main()
f[k]=s;
if (n<=1000)
distance();
}
洛谷 P1627 中位數
原題 考場想到了正解,但是依舊選擇了暴力,這究竟是天意,還是人覺啊!為了表示內心的惋惜與痛卻,還寫什麼解題思路啊!找到指定數的位置,算一遍字首和 如果a i include include include include include include include include include...
洛谷P1627 CQOI2009 中位數
給出1 n的乙個排列,統計該排列有多少個長度為奇數的連續子串行的中位數是b。中位數是指把所有元素從小到大排列後,位於中間的數。第一行為兩個正整數n和b,第二行為1 n的排列。資料規模 對於30 的資料中,滿足n 100 對於60 的資料中,滿足n 1000 對於100 的資料中,滿足n 100000...
洛谷 P1168 中位數
題目描述 給出乙個長度為n的非負整數序列a i 對於所有1 k n 1 2,輸出a 1 a 2 a 2k 1 的中位數。color red 即 color 前1,3,5,個數的中位數。輸入輸出格式 輸入格式 輸入檔案median.in的第1行為乙個正整數n,表示了序列長度。第2行包含n個非負整數a ...