題目鏈結
分塊。
\(p[i][j]\)表示第\(i\)個塊到第\(j\)個塊內的眾數,預處理出來就好了,列舉\(i\)和\(j\)是\(o(\sqrt n)\)的,列舉\(j\)塊內的數也是\(o(\sqrt n)\)的,總複雜度\(o(n\sqrt n)\)。
\(sum[i][h]\)表示前\(i\)個塊數字\(h\)出現的個數,預處理是\(o(n)\)的。
對於每乙個查詢,假設左端點\(l\)所在的塊是\(x\),右端點\(r\)所在的塊是\(y\),然後分情況:
如果\(y - x <= 2\),直接暴力,最多掃\(3 *\sqrt n\)個數,複雜度\(o( \sqrt n)\)。
如果\(y - x > 2\),我們可以確定這個眾數一定出現在兩邊的殘塊中或中間的整塊中,我們只需列舉殘塊中的每個數,用預處理出來的\(sum\)陣列求出整個區間某個數的個數,最後在與\(p[x + 1][y - 1]\),比較一下就好了,最多掃\(2 *\sqrt n\)個數,複雜度\(o( \sqrt n)\)。
#include using namespace std;
inline long long read()
const int n = 4e4 + 5;
int n, m, t, len, last;
int a[n], c[n], vis[n], pos[n], tong[n], pre[n], sum[205][n];
struct block b[n];
struct number p[205][205];
void make_pre()
else if(tong[a[k]] == tmp.num)
}p[i][j] = tmp;
}for(int j = i;j <= t; j++)
for(int k = b[j].l;k <= b[j].r; k++) tong[a[k]] = 0;
}for(int i = 1;i <= t; i++)
}int query(int l, int r)
return pre[tmp];
}else
} for(int i = b[y].l;i <= r; i++)
}int tmp = tong[ans] + p[x + 1][y - 1].num;
if(res_num > tmp) ans = res_x;
else if(res_num == tmp) ans = min(ans, res_x);
return pre[ans];
}}int main()
make_pre();
for(int i = 1, l, r;i <= m; i++)
return 0;
}
洛谷P4168 Violet 蒲公英 分塊
時空限制 2000ms 512mb 題目描述 在鄉下的小路旁種著許多蒲公英,而我們的問題正是與這些蒲公英有關。為了簡化起見,我們把所有的蒲公英看成乙個長度為n的序列 a 1,a 2 a n 其中ai為乙個正整數,表示第i棵蒲公英的種類編號。而每次詢問乙個區間 l,r 你需要回答區間裡出現次數最多的是...
洛谷 P4168 Violet 蒲公英 解題報告
親愛的哥哥 你在那個城市裡面過得好嗎?我在家裡面最近很開心呢。昨天晚上奶奶給我講了那個叫 絕望 的大壞蛋的故事的說!它把人們的房子和田地搞壞,還有好多小朋友也被它殺掉了。我覺得把那麼可怕的怪物召喚出來的那個壞蛋也很壞呢。不過奶奶說他是很難受的時候才做出這樣的事的 最近村子里長出了一大片一大片的蒲公英...
洛谷P4168 蒲公英 分塊
給出乙個長度為n n的序列,m m次詢問,求區間 l,r l r 以下內容參考lyd lyd 演算法競賽高階指南 先離散化不解釋。分塊演算法一般都是以 暴力 區間預處理 暴力 的方法做的。所以,我們把n n分成t t塊,每塊長度 tn nt 然後預處理出對於任意兩個區間內的數字個數。也就是說,對於任...