牛客网【每日一题】5月22日 [CQOI2009]中位数图
生活随笔
收集整理的這篇文章主要介紹了
牛客网【每日一题】5月22日 [CQOI2009]中位数图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
鏈接:
時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld題目描述
給出1~n的一個排列,統計該排列有多少個長度為奇數的連續子序列的中位數是b。中位數是指把所有元素從小到大排列后,位于中間的數。
輸入描述:
第一行為兩個正整數n和b ,第二行為1~n 的排列
輸出描述:
輸出一個整數,即中位數為b的連續子序列個數。
示例1
輸入
輸出
4題解:
b是中位數,在b后面的比b大,前面的比b小,比b大多少小多少都無所謂,所以我們可以把大于b的數記為1,小于的記為-1,相等的記為0,這樣的話,我們要找一個什么樣的區間?一個奇數區間的和是0且0的長度還是奇數(和為0說明左右兩邊-1和1數量相等,且最中間為0是我們所要的b)
我們可以以0開始分別分析左右兩邊,統計0的左邊后綴和為i的個數,右邊的前綴和為i的個數,為了保證兩邊數量相同,就要使右邊的前綴和與左邊的前綴和互為相反數。(左右前綴和均從0開始)
樣例:
5 7 2 4 3 1 6
化為-1,0,1
1 1 -1 0 -1 -1 1
0的左邊前綴和(從0開始)
1 0 -1
右邊
-1 -2 -1
左邊一個-1可以和右邊兩個-1搭配,兩個答案
左邊一個0,不與右邊搭配,一個答案
b本身,一個答案
總:四個答案
代碼:
(代碼僅提供思路)
#include<iostream> #include<cstdio> #include<algorithm> #define maxn 1e6+4 using namespace std; int a[maxn]; map<int,int >b; int main() {int n,m;cin>>n>>m;int pos,sum=0;for(int i=1;i<=n;i++){cin>>a[i];if(a[i]<m)a[i]=-1;else if(a[i]>m)a[i]=1;else {a[i]=0;pos=i;}}b[0]=1;//和為0則符合條件 int tot=0;for(int i=pos-1;i;i--){if(a[i]==1)sum--;//前綴和 else sum++;if(sum==0)tot++;//存在0就直接加 b[tot]++;}for(int i=pos+1;i<=n;i++){if(a[i]==1)sum--;else sum++:ans+=b[-sum];//查看相反數有多少個 }printf("%d",tot);return 0; }總結
以上是生活随笔為你收集整理的牛客网【每日一题】5月22日 [CQOI2009]中位数图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓页面删除怎么恢复(安卓页面删除)
- 下一篇: 牛客网 【每日一题】5月28日题目精讲