• BZOJ 3236: [Ahoi2013]作业


    3236: [Ahoi2013]作业

    Time Limit: 100 Sec  Memory Limit: 512 MB
    Submit: 1393  Solved: 562
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    3 4
    1 2 2
    1 2 1 3
    1 2 1 1
    1 3 1 3
    2 3 2 3

    Sample Output

    2 2
    1 1
    3 2
    2 1

    HINT


    N=100000,M=1000000

    Source

    [Submit][Status][Discuss]

    莫队算法 + 树状数组统计答案

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <algorithm>
      7 
      8 using namespace std;
      9 
     10 /* SCANNER */
     11 
     12 #define siz 10000000
     13 
     14 inline char get_a(void) {
     15     static char buf[siz], *bit = buf;
     16 
     17     if (bit == buf + siz)
     18         fread(bit = buf, 1, siz, stdin);
     19 
     20     return *bit++;
     21 }
     22 
     23 inline int get_i(void) {
     24     register int ret = 0;
     25     register int neg = false;
     26     register int bit = get_a();
     27 
     28     for (; bit < '0'; bit = get_a())
     29         if (bit == '-')neg ^= true;
     30 
     31     for (; bit >= '0'; bit = get_a())
     32         ret = ret * 10 + bit - '0';
     33 
     34     return neg ? -ret : ret;
     35 }
     36 
     37 #define maxn 400005
     38 #define maxm 1000005
     39 
     40 int s;
     41 int tot;
     42 int n, m;
     43 int num[maxn];
     44 int cnt[maxn];
     45 int tmp[maxn];
     46 int ans1[maxm];
     47 int ans2[maxm];
     48 int tree1[maxn];
     49 int tree2[maxn];
     50 
     51 struct query {
     52     int l, r, a, b, id;
     53 }qry[maxm];
     54 
     55 inline int cmp(const void *a, const void *b) {
     56     query *A = (query *)a;
     57     query *B = (query *)b;
     58     if (A->l / s != B->l / s)
     59         return A->l - B->l;
     60     else
     61         return A->r - B->r;
     62 }
     63 
     64 inline void add(int *t, int p, int k) {
     65     for (; p <= tot; p += p&-p)
     66         t[p] += k;
     67 }
     68 
     69 inline int ask(int *t, int p) {
     70     int ret = 0;
     71     for (; p; p -= p&-p)
     72         ret += t[p];
     73     return ret;
     74 }
     75 
     76 inline void remove(int t) {
     77     add(tree1, t, -1);
     78     if (--cnt[t] == 0)
     79         add(tree2, t, -1);
     80 }
     81 
     82 inline void insert(int t) {
     83     add(tree1, t, 1);
     84     if (++cnt[t] == 1)
     85         add(tree2, t, 1);
     86 }
     87 
     88 signed main(void) {
     89     n = get_i();
     90     m = get_i();
     91     s = sqrt(n);
     92 
     93     for (int i = 1; i <= n; ++i)
     94         num[i] = get_i(), tmp[++tot] = num[i];
     95 
     96     for (int i = 1; i <= m; ++i) {
     97         qry[i].id = i;
     98         qry[i].l = get_i();
     99         qry[i].r = get_i();
    100         qry[i].a = get_i();
    101         qry[i].b = get_i();
    102     }
    103 
    104     for (int i = 1; i <= m; ++i)
    105         tmp[++tot] = qry[i].a,
    106         tmp[++tot] = qry[i].b;
    107 
    108     sort(tmp + 1, tmp + 1 + tot);
    109 
    110     tot = unique(tmp + 1, tmp + 1 + tot) - tmp;
    111 
    112     for (int i = 1; i <= n; ++i)
    113         num[i] = lower_bound(tmp + 1, tmp + tot, num[i]) - tmp;
    114 
    115     for (int i = 1; i <= m; ++i) {
    116         qry[i].a = lower_bound(tmp + 1, tmp + tot, qry[i].a) - tmp;
    117         qry[i].b = lower_bound(tmp + 1, tmp + tot, qry[i].b) - tmp;
    118     }
    119 
    120     /*
    121     for (int i = 1; i <= n; ++i)
    122         printf("%d ", num[i]);
    123 
    124     puts("");
    125 
    126     for (int i = 1; i <= m; ++i)
    127         printf("%d %d
    ", qry[i].a, qry[i].b);
    128     */
    129 
    130     qsort(qry + 1, m, sizeof(query), cmp);
    131 
    132     int l = 1, r = 0;
    133 
    134     for (int i = 1; i <= m; ++i) {
    135         while (l < qry[i].l)remove(num[l++]);
    136         while (l > qry[i].l)insert(num[--l]);
    137         while (r < qry[i].r)insert(num[++r]);
    138         while (r > qry[i].r)remove(num[r--]);
    139         ans1[qry[i].id] = ask(tree1, qry[i].b) - ask(tree1, qry[i].a - 1);
    140         ans2[qry[i].id] = ask(tree2, qry[i].b) - ask(tree2, qry[i].a - 1);
    141     }
    142 
    143     for (int i = 1; i <= m; ++i)
    144         printf("%d %d
    ", ans1[i], ans2[i]);
    145 
    146     //system("pause");
    147 }
      1 #include <cmath>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <algorithm>
      7 
      8 using namespace std;
      9 
     10 /* SCANNER */
     11 
     12 #define siz 50000000
     13 
     14 inline int get_c(void)
     15 {
     16     static char buf[siz];
     17     static char *head = buf;
     18     static char *tail = buf + siz;
     19 
     20     if (head == tail)
     21         fread(head = buf, 1, siz, stdin);
     22 
     23     return *head++;
     24 }
     25 
     26     #define getc get_c
     27 //    #define getc getchar
     28 
     29 inline int get_i(void)
     30 {
     31     register int ret = 0;
     32     register int neg = false;
     33     register int bit = getc();
     34 
     35     for (; bit < '0'; bit = getc())
     36         if (bit == '-')neg ^= true;
     37 
     38     for (; bit >= '0'; bit = getc())
     39         ret = ret * 10 + bit - '0';
     40 
     41     return neg ? -ret : ret;
     42 }
     43 
     44 /* PROBLEM */
     45 
     46 #define maxn 100005
     47 #define maxm 1000005
     48 
     49 int n, m, s;
     50 int num[maxn];
     51 int cnt[maxm * 3];
     52 int tmp[maxm * 3];
     53 int *tot = tmp + 1;
     54 int tree1[maxm * 3];
     55 int tree2[maxm * 3];
     56 
     57 /* QRY */
     58 
     59 struct query
     60 {
     61     int l, r;
     62     int a, b;
     63     int ans1;
     64     int ans2;
     65 }qry[maxm], *ord[maxm];
     66 
     67 inline bool cmp(query *a, query *b) 
     68 {
     69     if (a->l / s != b->l / s)
     70         return a->l < b->l;
     71     else
     72         return a->r < b->r;
     73 }
     74 
     75 /* BIT */
     76 
     77 inline void add(int *t, int p, int k) 
     78 {
     79     int len = tot - tmp;
     80     for (; p <= len; p += p&-p)
     81         t[p] += k;
     82 }
     83 
     84 inline int ask(int *t, int p)
     85 {
     86     int ret = 0;
     87     for (; p; p -= p&-p)
     88         ret += t[p];
     89     return ret;
     90 }
     91 
     92 /* MOQ */
     93 
     94 inline void insert(int t)
     95 {
     96     add(tree1, t, +1);
     97     if (++cnt[t] == 1)
     98         add(tree2, t, +1);
     99 }
    100 
    101 inline void remove(int t)
    102 {
    103     add(tree1, t, -1);
    104     if (--cnt[t] == 0)
    105         add(tree2, t, -1);
    106 }
    107 
    108 /* MAIN */
    109 
    110 signed main(void) 
    111 {
    112     n = get_i();
    113     m = get_i();
    114     s = sqrt(n);
    115 
    116     for (int i = 1; i <= n; ++i)
    117         *tot++ = num[i] = get_i();
    118 
    119     for (int i = 1; i <= m; ++i) 
    120     {
    121         ord[i] = qry + i;
    122         qry[i].l = get_i();
    123         qry[i].r = get_i();
    124         *tot++ = qry[i].a = get_i();
    125         *tot++ = qry[i].b = get_i();
    126     }
    127 
    128     sort(tmp + 1, tot); 
    129 
    130     tot = unique(tmp + 1, tot);
    131 
    132     for (int i = 1; i <= n; ++i)
    133         num[i] = lower_bound(tmp + 1, tot, num[i]) - tmp;
    134 
    135     for (int i = 1; i <= m; ++i)
    136     {
    137         qry[i].a = lower_bound(tmp + 1, tot, qry[i].a) - tmp;
    138         qry[i].b = lower_bound(tmp + 1, tot, qry[i].b) - tmp;
    139     }
    140 
    141     sort(ord + 1, ord + 1 + m, cmp);
    142 
    143     int lt = 1, rt = 0;    // left & right
    144 
    145     for (int i = 1; i <= m; ++i)
    146     {
    147         query *q = ord[i];
    148         while (lt < q->l)remove(num[lt++]);
    149         while (lt > q->l)insert(num[--lt]);
    150         while (rt < q->r)insert(num[++rt]);
    151         while (rt > q->r)remove(num[rt--]);
    152         q->ans1 = ask(tree1, q->b) - ask(tree1, q->a - 1);
    153         q->ans2 = ask(tree2, q->b) - ask(tree2, q->a - 1);
    154     }
    155 
    156     for (int i = 1; i <= m; ++i)
    157         printf("%d %d
    ", qry[i].ans1, qry[i].ans2);
    158 
    159     //system("pause");
    160 }

    @Author: YouSiki

  • 相关阅读:
    HDOJ 1093
    HDOJ 1089
    HDOJ 1094
    qsort函数
    HDOJ 1092
    HDOJ 1091
    NYOJ 448(贪心)
    HDOJ 1090
    HDOJ 1097(幂取模)
    winform用户输入查询与拼音首字母的结合,提高用户的操作体验
  • 原文地址:https://www.cnblogs.com/yousiki/p/6193728.html
Copyright © 2020-2023  润新知