zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    How to Create a site at the specified URL and new database (CommandLine Operation)
    Using Wppackager to Package and Deploy Web Parts for Microsoft SharePoint Products and Technologies
    SQL Server Monitor v0.5 [Free tool]
    How to build Web Part
    Deploy web part in a virtual server by developing a Web Part Package file(.cab)
    How to recreate "sites" link if you delete it accidentally
    SharePoint Portal Server管理匿名访问设置
    Monitor sql connection from .Net SqlClient Data Provider
    Brief installation instruction of Sharepoint Portal Server
    How to Use SharePoint Alternate URL Access
  • 原文地址:https://www.cnblogs.com/yousiki/p/6193728.html
Copyright © 2011-2022 走看看