归并树一题

个人感觉相对划分树而言,归并树是基于归并排序的分治思想(归并排序也可以快速求逆序数)

归并树 hdu4417Super Mario (求给定数在给定区间的中比它小的数的个数,或大小位置)(求逆序数)

typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
const int INF = 1000000000;
const int maxn = 100010;
const int deep = 20;
 
//#define lson l, m, rt << 1, dep + 1
//#define rson m + 1, r, rt << 1 | 1,dep + 1
///可以不用 rt
 
#define lson l, m, dep + 1
#define rson m + 1, r, dep + 1
 
int t[deep][maxn];///tree[deep][maxn]///隐式线段树
int n;
int ans;
 
void build(int l, int r, int dep)///建立树///dep 从1开始
{
   for (int i = l; i <= r; i++) t[dep][i] = t[dep - 1][i];///复制到下面
   if (l == r) return ;///必须放到后面
   int m = (l + r) >> 1;
   build(lson);
   build(rson);
   sort(t[dep] + l, t[dep] + r + 1);///排序
}
 
///二分
int solve(int be, int ed, int x, int dep)
{
   int *num = t[dep];///技巧
   int l = be, r = ed, m;
   while (l <= r)
    {
       m = (l + r) >> 1;
       if (num[m] > x)///
            r = m - 1;
       else l = m + 1;
    }
   return l;
}
 
void query(int L, int R, int h, int l, intr, int dep)
{
   if (L <= l && r <= R)
    {
       int u = solve(l, r, h, dep);
       ans += u - l;
       return;
    }
   int m = (l + r) >> 1;
   if (m >= L) query(L, R, h, lson);
   if (m < R) query(L, R, h, rson);
}
 
int main()
{
   int x, y, z;
   int T;
   int p = 1;
   RI(T);
   while (T--)
    {
       printf("Case %d:\n",p++);
       CLR(t, 0);///用初始化吗
       int m;
       RII(n, m);
       FE(i, 1, n)///1开始
           RI(t[0][i]);
 
       build(1, n, 1);///根为第1层
 
       while (m--)
       {
           RIII(x, y, z);
           x++;
           y++;
           ans = 0;
           query(x, y, z, 1, n, 1);///根为第1层
           printf("%d\n",ans);
       }
    }
}
 


个人感觉相对划分树而言,归并树是基于归并排序的分治思想(归并排序也可以快速求逆序数)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值