bzoj3173【树状数组】【平衡树】

树状数组解法
个人遇到的问题:虽然知道这种问题首先要倒着处理出依次的真实位置。但是想法错了。。
我认为是倒着处理每个位置的真实位置为:插入的位置+当前位置之后插入位置比当前插入的位置小的数量
结果一直wa
后来找到了一组样例
6
0 1 2 0 3 4
用上面的方法位置结果实际上是错的。
是因为当某一个位置插入之后,当再次插入的位置比之前插入的位置大也会影响之前的位置。
正确方法是把所有位置置1,还是倒着处理,对于每个位置cc[i],找第一个前缀和等于cc[i]的位置,就是真实位置。找的话就用二分找。
找到值得位置后在用一次树状数组就行了。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
typedef long long ll;
const ll mod = 1e9+7;
int Case = 1;
int lowbit(int x) {
   
    return x&(-x);
}
int n, m, cc[maxn], id[maxn];
struct T2 {
   
  int T[maxn];
  int query(int pos) {
   
    int res = 0;
    for (int i = pos; i >= 1; i -= lowbit(i)) {
   
      res += T[i];
    }
    return res;
  }
  void update(int pos, int x) {
   
    for (int i = pos; i <= n; i += lowbit(i)) {
   
      T[i] += x;
    }
  }
} T2;
struct Tree {
   
  int T[maxn];
  int query(int pos) {
   
    int res = 0;
    for (int i = pos; i >= 1; i -= lowbit(i)) {
   
      res = max(res, T[i]);
    }
    return res;
  }
  void update(int pos, int num) {
   
    for
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值