Super Mario (Chairman of the tree + weights tree line)

Title: add a linker script
ideas: first discrete data, established in accordance with the Chairman of the tree weights, then for a height h, we find the answer is the number of intervals of not more than h, then we strike the mid later, if h is greater than mid, then the number of left subtree are less than the number of statistics on h so be left subtree, then the right subtree continue recursive solution, keep on going until a leaf node, return its value is ok, there is the height of our inquiry after also highly discrete. upper_bound do not find the time to find floated

#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<cstdio>
#define mod (10007)
#define middle (l+r)>>1
#define SIZE 1000000+5
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
typedef long double ld;
const int inf_max = 0x3f3f3f;
const ll Linf = 9e18;
const int maxn = 100000+100;
const long double E = 2.7182818;
const double eps=0.0001;
using namespace std;
inline int read()
{
    int f=1,res=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { res=res*10+ch-'0' ; ch=getchar(); }
    return f*res;
}
struct node
{
    int l,r,val;
}tree[maxn * 25];
int lsan[maxn],m,cnt,root[maxn],n,a[maxn],number = 1;

int getid(int x,int up) {
    return lower_bound(lsan + 1,lsan + 1 + up,x) - lsan;
}
void update(int l,int r,int &now,int last,int v) {
    tree[++cnt] = tree[last]; tree[cnt].val++; now=cnt; //建立主席树,顺带按照权值维护一下每个数的个数
    if(l == r) return ;
    int mid = middle;
    if(v <= mid) update(l,mid,tree[now].l,tree[last].l,v);
    else update(mid + 1,r,tree[now].r,tree[last].r,v);
}
int query(int l,int r,int l_rt,int r_rt,int k) {
    if(r <= k ) return tree[r_rt].val-tree[l_rt].val;  //整个左区间的数都不大于k 所以我们直接返回统计的数量,不需要递归
    if(l == r) return tree[r_rt].val - tree[l_rt].val;
    int mid = middle;
    if(k <= mid) return query(l,mid,tree[l_rt].l,tree[r_rt].l,k); //去左区间找
    else return query(mid + 1,r,tree[l_rt].r,tree[r_rt].r,k) + tree[tree[r_rt].l].val - tree[tree[l_rt].l].val;  //去右区间找,同时加上左区间的。
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        cnt = 0;
        memset(lsan,0,sizeof(lsan));
        memset(root,0,sizeof(root));
        memset(tree,0,sizeof(tree));
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n ;i++) scanf("%d",&a[i]),lsan[i] = a[i];
        sort(lsan + 1,lsan + 1 + n);
        int tot = unique(lsan + 1,lsan + 1 + n) - lsan - 1;
        for(int i = 1;i <= n; ++i) {
            update(1,tot,root[i],root[i-1],getid(a[i],tot));
        }
        printf("Case %d:\n",number++);
        for(int i = 1;i <= m; ++i) {  //这里m我写成了n,re10多次,艹
            int ql,qr,up;
            scanf("%d%d%d",&ql,&qr,&up);
            ql++;qr++;
            int pos = upper_bound(lsan+1,lsan+1+tot,up)-lsan;
           // printf("pos=%d\n",pos);
            if(pos == 1) { printf("0\n"); continue; }
            else if(pos > tot) { printf("%d\n",qr + 1 - ql); continue; }
            else
                printf("%d\n",query(1,tot,root[ql-1],root[qr],pos-1));
        }
    }
    return 0;
}

Published 33 original articles · won praise 14 · views 411

Guess you like

Origin blog.csdn.net/qq_44077455/article/details/103974980