CF(173E) Camping Groups

來源:互聯網
上載者:User

題目連結

題意:一個俱樂部有 n名成員,每名成員有兩個屬性:聲望r和年紀a(均為109)。若干個個可以組成一個小組,每個小組中有一名組長,要求這名組長的聲望高於其他成員且這名組長與組內任意成員的年齡差小於k,先給出10000條查詢,問如果a、b兩人在一個小組中,那麼這個小組最多可以有多少人。

解法:1.由於n和a相差很大,因此首先要對聲望和年紀進行離散化

          2.每個小組的最大成員數量由隊長決定,因此問題變為選一個在與ab年紀差均小於k的人中選一個其作為組長人數最多的一個,因此需要離線處理出每個人作為組長小組內的人數,由於每個人只能作為聲望小於等於自己的人的組長,因此先按聲望由小到大排序然後依次處理,用樹狀數組統計出當前年紀在a-k和a+k範圍內有多少人(由於是對離散化後的資料進行處理,因此要通過查詢前驅和後繼擷取結果)

         3.按每條查詢的聲望值(兩人聲望中較大值)排序,並處理出每條查詢兩個人的組長的年齡範圍:若a[i]<a[j],則可按a[j]-a[i]>k*2、k<a[j]-a[i]<=k*2、a[j]-a[i]<k三種情況討論,然後對查詢按由大到小處理,每次講聲望大於等於查詢的隊長的人數插入到線段樹中,在查詢年齡範圍內的最大值(注意在去前去後繼時判斷無解的情況)

看別人的代碼很簡單,two pointers加點小資料結構就搞定了,這樣做雖然很trivial但感覺比較直觀。


import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.StreamTokenizer;import java.util.Arrays;import java.util.Set;import java.util.TreeMap;public class CampingGroups173E {int maxn = 100010;class SegTree {class node {int left, right;int val;node(int l, int r) {left = l;right = r;val = -1;}int mid() {return (left + right) >> 1;}}node tree[] = new node[maxn * 3];void init(int idx, int l, int r) {tree[idx] = new node(l, r);if (l == r)return;int mid = tree[idx].mid();init(idx << 1, l, mid);init(idx << 1 | 1, mid + 1, r);}void update(int idx, int pos, int v) {if (pos == tree[idx].left & pos == tree[idx].right) {if (v > tree[idx].val)tree[idx].val = v;return;}int mid = tree[idx].mid();if (pos <= mid)update(idx << 1, pos, v);elseupdate(idx << 1 | 1, pos, v);tree[idx].val = Math.max(tree[idx << 1].val, tree[idx << 1 | 1].val);}int query(int idx, int l, int r) {if (tree[idx].left == l && tree[idx].right == r)return tree[idx].val;int mid = tree[idx].mid();if (r <= mid)return query(idx << 1, l, r);if (l > mid)return query(idx << 1 | 1, l, r);return Math.max(query(idx << 1, l, mid),query(idx << 1 | 1, mid + 1, r));}}class Leader implements Comparable<Leader> {int age, cap, id;Leader(int i, int a, int c) {id = i;age = a;cap = c;}public int compareTo(Leader oth) {if (cap < oth.cap)return -1;return 1;}}class Query implements Comparable<Query> {int id;long left, right, cap, ans;Query(int i, int a, int b) {id = i;cap = Math.max(c[a], c[b]);if (age[a] > age[b]) {int temp = a;a = b;b = temp;}long temp = age[b] - age[a];if (temp > 2 * k) {ans = -1;return;}if (temp <= k) {left = age[a] - (k - temp);right = age[b] + (k - temp);} else if (temp <= 2 * k) {left = age[b] - k;right = age[a] + k;}}public int compareTo(Query oth) {if (cap > oth.cap)return -1;return 1;}}class IndexedTree {int n, ss[] = new int[maxn];int b[] = new int[maxn];IndexedTree() {for (int i = 1; i < maxn; i++)b[i] = i & (-i);}void init(int n) {this.n = n;Arrays.fill(ss, 0);}void inc(int i, int k) {while (i <= n) {ss[i] += k;i += b[i];}}int get(int i) {int res = 0;while (i > 0) {res += ss[i];i -= b[i];}return res;}}StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));long next() throws IOException {in.nextToken();return (long) in.nval;}long age[] = new long[maxn], c[] = new long[maxn], k;SegTree st = new SegTree();IndexedTree it = new IndexedTree();Leader lead[] = new Leader[maxn];Query qq[] = new Query[maxn];TreeMap<Long, Integer> hashage = new TreeMap<Long, Integer>();TreeMap<Long, Integer> hashcap = new TreeMap<Long, Integer>();int n, m, cnt;void init() throws IOException {n = (int) next();k = next();for (int i = 1; i <= n; i++) {c[i] = next();hashcap.put(c[i], 0);}for (int i = 1; i <= n; i++) {age[i] = next();hashage.put(age[i], 0);}cnt = 0;Set<Long> set = hashcap.keySet();for (Long i : set)hashcap.put(i, ++cnt);cnt = 0;set = hashage.keySet();for (Long i : set)hashage.put(i, ++cnt);for (int i = 1; i <= n; i++)lead[i] = new Leader(i, hashage.get(age[i]), hashcap.get(c[i]));Arrays.sort(lead, 1, n + 1);m = (int) next();for (int i = 1; i <= m; i++)qq[i] = new Query(i, (int) next(), (int) next());Arrays.sort(qq, 1, m + 1);}int dp[] = new int[maxn];void work() {int i = 1;it.init(cnt);while (i <= n) {int j = i, temp = lead[j].cap;while (j <= n && lead[j].cap == temp)it.inc(lead[j++].age, 1);for (int p = i; p < j; p++) {int id = lead[p].id;int left = hashage.get(hashage.ceilingKey(age[id] - k));int right = hashage.get(hashage.floorKey(age[id] + k));dp[p] = it.get(right) - it.get(left - 1);}i = j;}st.init(1, 1, cnt);Arrays.fill(ans, -1);}int ans[] = new int[maxn];void query() {int ld = n;for (int i = 1; i <= m; i++) {int cap = hashcap.get(qq[i].cap);while (ld > 0 && lead[ld].cap >= cap)st.update(1, lead[ld].age, dp[ld--]);if (qq[i].ans != -1) {int left, right = 0;if (hashage.containsKey(qq[i].left))left = hashage.get(qq[i].left);elseleft = hashage.get(hashage.ceilingKey(qq[i].left));if (qq[i].right < hashage.firstKey())System.out.println(qq[i].id + " fuck");if (hashage.containsKey(qq[i].right))right = hashage.get(qq[i].right);elseright = hashage.get(hashage.floorKey(qq[i].right));if (left <= right)ans[qq[i].id] = st.query(1, left, right);}}}void run() throws IOException {init();work();query();for (int i = 1; i <= m; i++)System.out.println(ans[i]);}public static void main(String[] args) throws IOException {new CampingGroups173E().run();}}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.