zoukankan      html  css  js  c++  java
  • BZOJ 3744: Gty的妹子序列

    3744: Gty的妹子序列

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1335  Solved: 379
    [Submit][Status][Discuss]

    Description

    我早已习惯你不在身边,
    人间四月天 寂寞断了弦。
    回望身后蓝天,
    跟再见说再见……
    某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现
    她们排成了一个序列,每个妹子有一个美丽度。
    Bakser神犇与他打算研究一下这个妹子序列,于是Bakser神犇问道:"你知道区间
    [l,r]中妹子们美丽度的逆序对数吗?"
    蒟蒻Autumn只会离线乱搞啊……但是Bakser神犇说道:"强制在线。"
    请你帮助一下Autumn吧。
    给定一个正整数序列a,对于每次询问,输出al...ar中的逆序对数,强制在线。

    Input

    第一行包括一个整数n(1<=n<=50000),表示数列a中的元素数。
    第二行包括n个整数a1...an(ai>0,保证ai在int内)。
    接下来一行包括一个整数m(1<=m<=50000),表示询问的个数。
    接下来m行,每行包括2个整数l、r(1<=l<=r<=n),表示询问al...ar中的逆序
    对数(若ai>aj且i<j,则为一个逆序对)。
    l,r要分别异或上一次询问的答案(lastans),最开始时lastans=0。
    保证涉及的所有数在int内。

    Output

    对每个询问,单独输出一行,表示al...ar中的逆序对数。

    Sample Input

    4
    1 4 2 3
    1
    2 4

    Sample Output

    2

    HINT

    Source

    [Submit][Status][Discuss]

    ╮(╯▽╰)╭  Gty的撩妹技能我等蒟蒻就是不能比。

    分块+主席树+树状数组 随便搞一发就好了(其实调了好久)。

      1 #include <bits/stdc++.h>
      2 
      3 namespace fastRead
      4 {
      5     inline int nextChar(void)
      6     {
      7         static const int siz = 1 << 20;
      8 
      9         static char buf[siz];
     10         static char *hd = buf + siz;
     11         static char *tl = buf + siz;
     12 
     13         if (hd == tl)
     14             fread(hd = buf, 1, siz, stdin);
     15 
     16         return int(*hd++);
     17     }
     18 
     19     inline int nextInt(void)
     20     {
     21         register int ret = 0;
     22         register int neg = false;
     23         register int bit = nextChar();
     24 
     25         for (; bit < 48; bit = nextChar())
     26             if (bit == '-')neg ^= true;
     27 
     28         for (; bit > 47; bit = nextChar())
     29             ret = ret * 10 + bit - '0';
     30 
     31         return neg ? -ret : ret;
     32     }
     33 }
     34 
     35 const int mxn = 50005;
     36 
     37 int n, m, h, s[mxn], lastAns = 0;
     38 
     39 namespace chairManTree
     40 {
     41     const int siz = 1000005;
     42 
     43     int tot;
     44     int cnt[siz];
     45     int lsn[siz];
     46     int rsn[siz];
     47 
     48     int root[mxn];
     49 
     50     void insert(int &t, int p, int l, int r, int v)
     51     {
     52         t = ++tot;
     53 
     54         lsn[t] = lsn[p];
     55         rsn[t] = rsn[p];
     56         cnt[t] = cnt[p] + 1;
     57 
     58         if (l != r)
     59         {
     60             int mid = (l + r) >> 1;
     61     
     62             if (v <= mid)
     63                 insert(lsn[t], lsn[p], l, mid, v);
     64             else
     65                 insert(rsn[t], rsn[p], mid + 1, r, v);
     66         }
     67     }
     68 
     69     int query(int a, int b, int l, int r, int x, int y)
     70     {
     71         if (l == x && r == y)
     72             return cnt[a] - cnt[b];
     73         
     74         int mid = (l + r) >> 1;
     75 
     76         if (y <= mid)
     77             return query(lsn[a], lsn[b], l, mid, x, y);
     78         else if (x > mid)
     79             return query(rsn[a], rsn[b], mid + 1, r, x, y);
     80         else
     81             return query(lsn[a], lsn[b], l, mid, x, mid) + query(rsn[a], rsn[b], mid + 1, r, mid + 1, y);
     82     }
     83 
     84     inline void main(void)
     85     {
     86         for (int i = 1; i <= n; ++i)
     87             insert(root[i], root[i - 1], 1, h, s[i]);
     88     }
     89 
     90     inline int query(int l, int r, int k)
     91     {
     92         if (k > 1)
     93             return query(root[r], root[l - 1], 1, h, 1, k - 1);
     94         else
     95             return 0;
     96     }
     97 }
     98 
     99 namespace binaryInsertTree
    100 {
    101     int tree[mxn];
    102 
    103     inline void add(int p, int v)
    104     {
    105         for (; p <= h; p += p&-p)
    106             tree[p] += v;
    107     }
    108 
    109     inline int qry(int p)
    110     {
    111         int ret = 0;
    112 
    113         for (; p >= 1; p -= p&-p)
    114             ret += tree[p];
    115 
    116         return ret;
    117     }
    118 
    119     inline void init(void)
    120     {
    121         memset(tree, 0, sizeof(tree));
    122     }
    123 }
    124 
    125 namespace divideSequence
    126 {
    127     const int mxt = 255;
    128 
    129     int t, st[mxt], tot, rev[mxt][mxn];
    130 
    131     inline int findStart(int k)
    132     {
    133         int lt = 1, rt = tot, mid, ans = 0;
    134 
    135         while (lt <= rt)
    136         {
    137             mid = (lt + rt) >> 1;
    138 
    139             if (st[mid] >= k)
    140                 rt = mid - 1, ans = mid;
    141             else
    142                 lt = mid + 1;
    143         }
    144 
    145         return ans;
    146     }
    147 
    148     inline void main(void)
    149     {
    150         t = int(sqrt(n) + 0.5);
    151 
    152         for (int i = 1, j = 1; i <= n; i += t, ++j)
    153         {
    154             st[j] = i;
    155 
    156             binaryInsertTree::init();
    157 
    158             for (int k = i, sum = 0; k <= n; ++k, ++sum)
    159             {
    160                 rev[j][k] = rev[j][k - 1];
    161                 rev[j][k] += sum - binaryInsertTree::qry(s[k]);
    162 
    163                 binaryInsertTree::add(s[k], 1);
    164             }
    165 
    166             tot = j;
    167         }
    168     }
    169 }
    170 
    171 namespace preworkHash
    172 {
    173     int map[mxn], tot;
    174 
    175     inline int find(int k)
    176     {
    177         int lt = 1, rt = tot, mid, ans;
    178 
    179         while (lt <= rt)
    180         {
    181             mid = (lt + rt) >> 1;
    182 
    183             if (map[mid] <= k)
    184                 lt = mid + 1, ans = mid;
    185             else
    186                 rt = mid - 1;
    187         }
    188 
    189         return ans;
    190     }
    191 
    192     inline void main(void)
    193     {
    194         for (int i = 1; i <= n; ++i)
    195             map[i] = s[i];
    196 
    197         std::sort(map + 1, map + 1 + n);
    198 
    199         for (int i = 1; i <= n; ++i)
    200             if (!tot || map[i] != map[tot])
    201                 map[++tot] = map[i];
    202 
    203         for (int i = 1; i <= n; ++i)
    204             s[i] = find(s[i]);
    205 
    206         h = tot;
    207     }
    208 }
    209 
    210 inline int solve(int l, int r)
    211 {
    212     int id = divideSequence::findStart(l), st, ret;
    213     
    214     if (id)
    215     {
    216         st = divideSequence::st[id];
    217         ret = divideSequence::rev[id][r];
    218     }
    219     else
    220         st = r + 1, ret = 0;
    221 
    222     if (st > r)
    223         st = r + 1;
    224     
    225     for (int i = l; i < st; ++i)
    226         ret += chairManTree::query(st, r, s[i]);
    227     
    228     binaryInsertTree::init();
    229 
    230     for (int i = l, sum = 0; i < st; ++i, ++sum)
    231     {
    232         ret += sum - binaryInsertTree::qry(s[i]);
    233         
    234         binaryInsertTree::add(s[i], 1);
    235     }
    236 
    237     return ret;
    238 }
    239 
    240 signed main(void)
    241 {
    242     n = fastRead::nextInt();
    243 
    244     for (int i = 1; i <= n; ++i)
    245         s[i] = fastRead::nextInt();
    246 
    247     preworkHash::main();
    248 
    249     chairManTree::main();
    250 
    251     divideSequence::main();
    252 
    253     m = fastRead::nextInt();
    254 
    255     for (int i = 1; i <= m; ++i)
    256     {
    257         int l = fastRead::nextInt();
    258         int r = fastRead::nextInt();
    259 
    260         l ^= lastAns;
    261         r ^= lastAns;
    262 
    263         printf("%d
    ", lastAns = solve(l, r));
    264     }
    265 }

    @Author: YouSiki

  • 相关阅读:
    RAND函数和SRAND函数
    称丢手帕问题
    用GDB调试程序(七)
    用GDB调试程序(六)
    用GDB调试程序(三)
    用GDB调试程序(五)
    用GDB调试程序(二)
    用GDB调试程序(一)
    SOAP 简单对象访问协议
    关于angularJS绑定数据时自动转义html标签
  • 原文地址:https://www.cnblogs.com/yousiki/p/6404863.html
Copyright © 2011-2022 走看看