zoukankan      html  css  js  c++  java
  • bzoj 2141 : 排队 分块

    题目链接

    2141: 排队

    Time Limit: 4 Sec  Memory Limit: 259 MB
    Submit: 1169  Solved: 465
    [Submit][Status][Discuss]

    Description

    排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。

    Input

    第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi¬,表示交换位置ai与位置bi的小朋友。

    Output

    输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。

    Sample Input

    【样例输入】
    3
    130 150 140
    2
    2 3
    1 3

    Sample Output

    1
    0
    3
     
     
    每次交换两个数, 求交换之后的逆序对的个数。
     
    思路:  我们分块来做, 如果要交换的两个数x, y在同一块里, 那么就暴力计算。 否则的话, 暴力计算x+1到x这个块的最右边, 和y-1到y这个块的最左边, 两个块中间的块用二分查找来计算。
    弱智错误查了一个小时...
      1 #include <iostream>
      2 #include <vector>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #include <cmath>
      7 #include <map>
      8 #include <set>
      9 #include <string>
     10 #include <queue>
     11 #include <stack>
     12 #include <bitset>
     13 using namespace std;
     14 #define pb(x) push_back(x)
     15 #define ll long long
     16 #define mk(x, y) make_pair(x, y)
     17 #define lson l, m, rt<<1
     18 #define mem(a) memset(a, 0, sizeof(a))
     19 #define rson m+1, r, rt<<1|1
     20 #define mem1(a) memset(a, -1, sizeof(a))
     21 #define mem2(a) memset(a, 0x3f, sizeof(a))
     22 #define rep(i, n, a) for(int i = a; i<n; i++)
     23 #define fi first
     24 #define se second
     25 typedef pair<int, int> pll;
     26 const double PI = acos(-1.0);
     27 const double eps = 1e-8;
     28 const int mod = 1e9+7;
     29 const int inf = 1061109567;
     30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
     31 const int maxn = 2e4+5;
     32 int a[maxn], b[maxn], c[maxn], sum[maxn], l[maxn], r[maxn], belong[maxn];
     33 int block, cnt, n, ans;
     34 int lowbit(int x) {
     35     return x&(-x);
     36 }
     37 void update(int x) {
     38     for(int i = x; i<=n; i+=lowbit(i)) {
     39         sum[i]++;
     40     }
     41 }
     42 int query(int x) {
     43     int ret = 0;
     44     for(int i = x; i>0; i-=lowbit(i)) {
     45         ret += sum[i];
     46     }
     47     return ret;
     48 }
     49 void rebuild(int x) {
     50     for(int i = l[x]; i<=r[x]; i++)
     51         b[i] = a[i];
     52     sort(b+l[x], b+r[x]+1);
     53 }
     54 void pre() {
     55     for(int i = n; i>0; i--) {
     56         ans += query(a[i]-1);
     57         update(a[i]);
     58     }
     59     for(int i = 1; i<=cnt; i++) {
     60         rebuild(i);
     61     }
     62 }
     63 void cmp(int x, int y) {
     64     if(x>y)
     65         ans++;          
     66     if(x<y)         //不要写else...可能相等
     67         ans--;
     68 }
     69 void solve(int x, int y) {
     70     if(a[x]>a[y])
     71         ans--;
     72     if(a[x]<a[y])       //不要写else!!
     73         ans++;
     74     if(belong[x] == belong[y]) {
     75         for(int i = x+1; i<y; i++) {
     76             cmp(a[i], a[x]);
     77             cmp(a[y], a[i]);
     78         }
     79     } else {
     80         for(int i = x+1; i<=r[belong[x]]; i++) {
     81             cmp(a[i], a[x]);
     82             cmp(a[y], a[i]);
     83         }
     84         for(int i = l[belong[y]]; i<y; i++) {
     85             cmp(a[i], a[x]);
     86             cmp(a[y], a[i]);
     87         }
     88         for(int i = belong[x]+1; i<belong[y]; i++) {
     89             ans -= lower_bound(b+l[i], b+r[i]+1, a[x])-b-1-l[i];
     90             ans += lower_bound(b+l[i], b+r[i]+1, a[y])-b-1-l[i];
     91             ans -= r[i] - (upper_bound(b+l[i], b+r[i]+1, a[y])-b-l[i]);
     92             ans += r[i] - (upper_bound(b+l[i], b+r[i]+1, a[x])-b-l[i]);
     93         }
     94     }
     95     swap(a[x], a[y]);
     96     rebuild(belong[x]);
     97     rebuild(belong[y]);
     98 }
     99 int main()
    100 {
    101     int m;
    102     cin>>n;
    103     block = sqrt(1.0*n);
    104     if(n%block)
    105         cnt = n/block+1;
    106     else
    107         cnt = n/block;
    108     for(int i = 1; i<=cnt; i++) {
    109         l[i] = (i-1)*block+1;
    110         r[i] = i*block;
    111     }
    112     r[cnt] = n;
    113     for(int i = 1; i<=n; i++) {
    114         scanf("%d", &a[i]);
    115         c[i-1] = a[i];
    116         belong[i] = (i-1)/block+1;
    117     }
    118     sort(c, c+n);
    119     int tmp = unique(c, c+n)-c;
    120     for(int i = 1; i<=n; i++) {
    121         a[i] = b[i] = lower_bound(c, c+tmp, a[i])-c+1;
    122     }
    123     pre();
    124     cout<<ans<<endl;
    125     cin>>m;
    126     while(m--) {
    127         int x, y;
    128         scanf("%d%d", &x, &y);
    129         if(x>y)
    130             swap(x, y);
    131         solve(x, y);
    132         printf("%d
    ", ans);
    133     }
    134     return 0;
    135 }
  • 相关阅读:
    Spring AOP切点表达式用法总结
    各种文档地址记录
    回顾乐信集团工作经历
    Redux的简单使用
    简单介绍软件测试(一)
    jupyter notebook 安装代码提示功能
    解决matplotlib不显示中文的问题
    前端生成二维码并下载(PC端)
    XSS绕过常见方式
    JWT的安全问题
  • 原文地址:https://www.cnblogs.com/yohaha/p/5263329.html
Copyright © 2011-2022 走看看