bzoj 2653 洛谷 P2839 [国家集训队] middle
生活随笔
收集整理的這篇文章主要介紹了
bzoj 2653 洛谷 P2839 [国家集训队] middle
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2653: middle
Time Limit:?20 Sec??Memory Limit:?512 MBSubmit:?2381??Solved:?1340
[Submit][Status][Discuss]
Description
一個長度為n的序列a,設其排過序之后為b,其中位數定義為b[n/2],其中a,b從0開始標號,除法取下整。給你一個 長度為n的序列s。回答Q個這樣的詢問:s的左端點在[a,b]之間,右端點在[c,d]之間的子序列中,最大的中位數。 其中a<b<c<d。位置也從0開始標號。我會使用一些方式強制你在線。?
Input
第一行序列長度n。接下來n行按順序給出a中的數。 接下來一行Q。然后Q行每行a,b,c,d,我們令上個詢問的答案是 x(如果這是第一個詢問則x=0)。 令數組q={(a+x)%n,(b+x)%n,(c+x)%n,(d+x)%n}。 將q從小到大排序之后,令真正的 要詢問的a=q[0],b=q[1],c=q[2],d=q[3]。 輸入保證滿足條件。 第一行所謂“排過序”指的是從小到大排序! n<=20000,Q<=25000 ??
Output
Q行依次給出詢問的答案。
?
Sample Input
5170337785
271451044
22430280
969056313
206452321
3
3 1 0 2
2 3 1 4
3 1 4 0
Sample Output
271451044271451044
969056313 emmm這道題就是一道二分答案加主席樹 二分我的中位數是什么 然后check判斷他是否滿足條件 那么怎么判斷呢 對于一段區間 我們假設現在我們要check的中位數是x ?對應這個區間我們建立一棵線段樹 若一個數?≥ x 那么這個數在對應線段樹里面的值設為1 否則設為 - 1?
那么對應這一段的區間和如果等于0 那么這個數就可以作為這段區間的中位數 如果 > 0 則表示這段區間內比他大的數偏多 也就是說我們現在枚舉的這個數相對于中位數偏小 反之偏大 那么很顯然這個東西是滿足二分的? 但是又出現了一個問題 就是我們怎么搞每一個數對應的區間的值吧 肯定不可能是對于每一個數都開一棵線段樹 但是肯定不可能 時間空間都不夠用 ?這時候就想到了主席樹? 然而這個主席樹是怎么建立的呢 我們先對應所有的值都排一邊序(要存儲他們的原位置) 那么對于i + 1這個位置上的數對應的主席樹 他相對于 i 這個位置上的數對應的主席樹 發生的變化是不是就是將原數組中 i 對應的位置上的值從 1 改成 - 1 所以就很容易維護了 那么怎么對于[a,b] [c,d]查詢呢 按照題意 [b,c]是必須選的 求區間和即可那么要使中位數最大 就要使我們所求的區間和盡可能大 也就是求從b起向左的最大區間和 和從c起向右的最大區間和 求個和 根據上述判斷方式二分 然后就這樣 我wa了好幾次 竟然是查詢右兒子的時候寫的是 l 到 mid 丟臉... 代碼 #include <bits/stdc++.h> using namespace std;const int N = 20000 + 10; int a,b,c,d,T,n,w[N],sum[32 * N],ls[32 * N],rs[32 * N]; int rmax[32 * N],lmax[32 * N],rt,root[N],q[10],ans = 0;struct node{int val,pos; }s[N];void update(int nd) {sum[nd] = sum[ls[nd]] + sum[rs[nd]];rmax[nd] = max(rmax[rs[nd]],sum[rs[nd]] + rmax[ls[nd]]);lmax[nd] = max(lmax[ls[nd]],sum[ls[nd]] + lmax[rs[nd]]); }int build(int l,int r) {int nd = ++ rt;if(l == r) {sum[nd] = lmax[nd] = rmax[nd] = 1;return nd;}int mid = (l + r) >> 1;ls[nd] = build(l,mid);rs[nd] = build(mid + 1,r);update(nd);return nd; }int modify(int pre,int l,int r,int pos) {int nd = ++ rt;sum[nd] = sum[pre]; ls[nd] = ls[pre],rs[nd] = rs[pre];if(l == r) {sum[nd] = -1;rmax[nd] = 0;lmax[nd] = 0;return nd;}int mid = (l + r) >> 1;if(pos <= mid) ls[nd] = modify(ls[pre],l,mid,pos);else rs[nd] = modify(rs[pre],mid + 1,r,pos);update(nd);return nd; }bool cmp(const node & a,const node & b) {return a.val < b.val; }int query(int nd,int l,int r,int L,int R) {if(l > R || r < L) return 0;if(l >= L && r <= R) return sum[nd];int mid = (l + r) >> 1,ans = 0;if(L <= mid) ans += query(ls[nd],l,mid,L,R);if(mid < R) ans += query(rs[nd],mid + 1,r,L,R);return ans; }int query_r(int nd,int l,int r,int L,int R) {if(l > R || r < L) return 0;if(l >= L && r <= R) return rmax[nd];int mid = (l + r) >> 1,ans = 0;if(mid < R) ans = query_r(rs[nd],mid + 1,r,L,R);if(L <= mid) {int l_rmax = query_r(ls[nd],l,mid,L,R);int r_sum = query(ls[nd],mid + 1,r,L,R);ans = max(ans,l_rmax + r_sum);}return ans; }int query_l(int nd,int l,int r,int L,int R) {if(L > R) return 0; if(l >= L && r <= R) return lmax[nd];int mid = (l + r) >> 1,ans = 0;if(L <= mid) ans = query_l(ls[nd],l,mid,L,R);if(mid < R) {int r_lmax = query_l(ls[nd],mid + 1,r,L,R);int l_sum = query(ls[nd],l,mid,L,R);ans = max(ans,r_lmax + l_sum);}return ans; }bool check(int mid) {int ab = query_r(root[mid],1,n,q[1],q[2] - 1);int bc = query(root[mid],1,n,q[2],q[3]);int cd = query_l(root[mid],1,n,q[3] + 1,q[4]);if(ab + bc + cd >= 0) return true;return false; }int find( ) {int l = 1,r = n,ans = 0;while(l <= r) {int mid = (l + r) >> 1;if(check(mid)) ans = mid,l = mid + 1;else r = mid - 1;}return ans; }int main( ) {scanf("%d",& n);for(int i = 1;i <= n;i ++) {scanf("%d",& w[i]);s[i].pos = i; s[i].val = w[i];}sort(s + 1,s + n + 1,cmp);scanf("%d",& T);root[1] = build(1,n);for(int i = 2;i <= n;i ++) {root[i] = modify(root[i - 1],1,n,s[i - 1].pos);}while(T --) {scanf("%d%d%d%d",& a,& b,& c,& d);q[1] = (a + ans) % n + 1; q[2] = (b + ans) % n + 1;q[3] = (c + ans) % n + 1; q[4] = (d + ans) % n + 1;sort(q + 1,q + 5);ans = s[find( )].val;printf("%d\n",ans);} }
?
轉載于:https://www.cnblogs.com/Rubenisveryhandsome/p/9508058.html
總結
以上是生活随笔為你收集整理的bzoj 2653 洛谷 P2839 [国家集训队] middle的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华擎主板bios设置图解_华擎主板bio
- 下一篇: cubase流水账