uva 11990 块状链表

想了想树套树比较难写,于是块链试一下,2秒左右过了。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <cmath>
  6 using namespace std;
  7 
  8 typedef long long ll;
  9 const int INF = 9999999;
 10 const int N = 200001;
 11 const int M = 1000;
 12 int b[M][M];
 13 int sz[M];
 14 int a[N];
 15 int d[N];
 16 int n, m, ps, k;
 17 
 18 void remove( int num )
 19 {
 20     int pos = d[num];
 21     int cur = pos / ps;
 22     int w = lower_bound( b[cur], b[cur] + sz[cur], num ) - b[cur];
 23     for ( int i = w; i < sz[cur] - 1; i++ )
 24     {
 25         b[cur][i] = b[cur][i + 1];
 26     }
 27     sz[cur]--;
 28     a[d[num]] = INF;
 29 }
 30 
 31 int query( int num )
 32 {
 33     int pos = d[num];
 34     int cur = pos / ps;
 35     int s = 0, c = 0;
 36     for ( int i = 0; i < cur; i++ )
 37     {
 38         if ( sz[i] )
 39         {
 40             s += sz[i];
 41             c += upper_bound( b[i], b[i] + sz[i], num ) - b[i];
 42         }
 43     }
 44     for ( int i = cur * ps; i < pos; i++ )
 45     {
 46         if ( a[i] != INF )
 47         {
 48             s++;
 49             if ( a[i] < num ) c++;
 50         }
 51     }
 52     s -= c;
 53     for ( int i = cur + 1; i < k; i++ )
 54     {
 55         if ( sz[i] )
 56         {
 57             s += upper_bound( b[i], b[i] + sz[i], num ) - b[i];
 58         }
 59     }
 60     int bound = min( n, ( cur + 1 ) * ps );
 61     for ( int i = pos + 1; i < bound; i++ )
 62     {
 63         if ( a[i] < num )
 64         {
 65             s++;
 66         }
 67     }
 68     return s;
 69 }
 70 
 71 int main ()
 72 {
 73     while ( scanf("%d%d", &n, &m) != EOF )
 74     {
 75         ps = 800;
 76         for ( int i = 0; i < n; i++ )
 77         {
 78             scanf("%d", &a[i]);
 79             b[i / ps][i % ps] = a[i];
 80             d[a[i]] = i;
 81         }
 82         k = ( n + ps - 1 ) / ps;
 83         for ( int i = 0; i < k - 1; i++ )
 84         {
 85             sz[i] = ps;
 86             sort( b[i], b[i] + sz[i] );
 87         }
 88         sz[k - 1] = n - ( k - 1 ) * ps;
 89         sort( b[k - 1], b[k - 1] + sz[k - 1] );
 90         ll ans = 0;
 91         for ( int i = 1; i <= n; i++ )
 92         {
 93             ans += query(i);
 94         }
 95         ans = ans / 2;
 96         for ( int i = 0; i < m; i++ )
 97         {
 98             printf("%lld\n", ans);
 99             int tmp;
100             scanf("%d", &tmp);
101             ans -= query(tmp);
102             remove(tmp);
103         }
104     }
105     return 0;
106 }

 

转载于:https://www.cnblogs.com/huoxiayu/p/4851546.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值