日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

D. Cut and Stick(Codeforces Round #716 (Div. 2))

發布時間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 D. Cut and Stick(Codeforces Round #716 (Div. 2)) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

D. Cut and Stick

給定一個長度為nnn的數組,里面元素為a1,a2,a3,…,an?1,an,(1≤ai≤n)a_1, a_2, a_3, \dots, a_{n- 1}, a_n, (1 \leq a_i \leq n)a1?,a2?,a3?,,an?1?,an?,(1ai?n),有mmm次詢問,每次給定l,rl, rl,r

問如果把[l,r][l, r][l,r]劃分若干段子序列,假設其中一段長度為lenlenlen,里面出現最多次的元素次數≤?len2?\leq \lceil \frac{len}{2} \rceil?2len??,對所有段都滿足,

不考慮劃分成一段的情況,那么我們就是要盡可能地把最大地給劃開,最優的策略是兩個最大的跟一個其他的一起劃分,

假設區間長度為r?l+1=lenr - l + 1 = lenr?l+1=len,最大的元素個數為xxx,則還有len?xlen - xlen?x個其他元素,

由于其他元素都是小于?len2?\lceil \frac{len}{2} \rceil?2len??的,所以,我們讓兩個最大元素與其他元素配對時,可以保證剩下的元素中最大個數不會超過xxx的值,

假設我們要配對kkk個,則當滿足,x?2k+len?x?k+1≥2x?4kx - 2k + len - x - k + 1 \geq 2x - 4kx?2k+len?x?k+12x?4k時只需要一個序列即可,解得k=2x?len?1k = 2x - len - 1k=2x?len?1

所以最后答案為max(2x?len,1)max(2x - len, 1)max(2x?len,1),所以我們只要統計區間數量最多的值即可,可用莫隊解決。

#include <bits/stdc++.h>using namespace std;const int N = 1e6 + 10;int a[N], ans[N], sum[N], num[N], n, m, block, maxn;struct Res {int l, r, id; }query[N];bool cmp(Res x, Res y) {return ((x.l / block) != (y.l / block)) ? x.l < y.l : ((x.l / block) & 1) ? x.r < y.r : x.r > y.r; }void add(int x) {num[a[x]]++;sum[num[a[x]]]++;while (sum[maxn + 1]) {maxn++;} }void del(int x) {sum[num[a[x]]]--;num[a[x]]--;while (maxn && !sum[maxn]) {maxn--;} }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d %d", &n, &m);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);}block = sqrt(n);for (int i = 1, l, r; i <= m; i++) {scanf("%d %d", &l, &r);query[i] = {l, r, i};}sort(query + 1, query + 1 + m, cmp);int l = 1, r = 0;for (int i = 1; i <= m; i++) {while (r < query[i].r) {add(++r);}while (l < query[i].l) {del(l++);}while (r > query[i].r) {del(r--);}while (l > query[i].l) {add(--l);}ans[query[i].id] = max(1, 2 * maxn - (query[i].r - query[i].l + 1));}for (int i = 1; i <= m; i++) {printf("%d\n", ans[i]);}return 0; }

總結

以上是生活随笔為你收集整理的D. Cut and Stick(Codeforces Round #716 (Div. 2))的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。