luogu P2617 Dynamic Rankings 主席树套树状数组模板

题目链接

树套树模板

#include<bits/stdc++.h>

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define LL long long
#define pii pair<int,int>
#define SZ(x) (int)x.size()
#define all(x) x.begin(),x.end()

using namespace std;

LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}
LL lcm(LL a, LL b) {return a / gcd(a, b) * b;}
LL powmod(LL a, LL b, LL MOD) {LL ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
const int N = 1e5 + 3;
const LL mod = 1e9 + 7;
int n,m,a[N],b[N<<1],cnT,tot,now,T[N<<1],Q[N*170],cnt;
struct uzi{int sta;char x;int l,r,k;}p[N];
int newnode(){int p=tot?Q[tot--]:++cnT;return p;}
struct faker{int sum,l,r;}t[N*170];
void up(int &x,int y,int l,int r,int pos,int val){
    if(!x){x=newnode();t[x].sum=t[x].l=t[x].r=0;}
    t[x]=t[y];t[x].sum+=val;
    if(l==r)return ;int mid=l+r>>1;
    if(pos<=mid)up(t[x].l,t[y].l,l,mid,pos,val);
    else up(t[x].r,t[y].r,mid+1,r,pos,val);
    if(!t[x].sum)Q[++tot]=x,x=0;
}
int totx,toty;
int L[100],R[100];
int get(int l,int r,int x){
    if(l==r)return l;
    int Y=0;
    int mid=l+r>>1;
    for(int i=1;i<=toty;i++)Y+=t[t[R[i]].l].sum;
    for(int i=1;i<=totx;i++)Y-=t[t[L[i]].l].sum;
    if(Y>=x){
        for(int i=1;i<=toty;i++)R[i]=t[R[i]].l;
        for(int i=1;i<=totx;i++)L[i]=t[L[i]].l;
        return get(l,mid,x);
    }
    else{
        for(int i=1;i<=toty;i++)R[i]=t[R[i]].r;
        for(int i=1;i<=totx;i++)L[i]=t[L[i]].r;
        return get(mid+1,r,x-Y);
    }
}
int main() {
	ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i],b[++cnt]=a[i];
    for(int i=1;i<=m;i++){
        int l,r,k;
        char x;
        cin>>x;
        if(x=='Q'){
            cin>>l>>r>>k;
            p[i]={0,x,l,r,k};
        }else {
            cin>>l>>r;
            p[i]={1,x,l,r,0};
            b[++cnt]=r;
        }
    }
    sort(b+1,b+1+cnt);
    cnt=unique(b+1,b+1+cnt)-b-1;
    for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+cnt,a[i])-b;
    for(int i=1;i<=m;i++)if(p[i].sta)p[i].r=lower_bound(b+1,b+1+cnt,p[i].r)-b;
    for(int i=1;i<=n;i++)for(int j=i;j<=n;j+=j&-j)up(T[j],T[j],1,cnt,a[i],1);
    for(int i=1;i<=m;i++){
        if(!p[i].sta){
            totx=toty=0;
            for(int j=p[i].l-1;j;j-=j&-j)L[++totx]=T[j];
            for(int j=p[i].r;  j;j-=j&-j)R[++toty]=T[j];
            //cout<<get(1,cnt,p[i].k)<<' ';
            cout<<b[get(1,cnt,p[i].k)]<<endl;
        }else{
            for(int j=p[i].l;j<=n;j+=j&-j)up(T[j],T[j],1,cnt,a[p[i].l],-1);
            a[p[i].l]=p[i].r;
            for(int j=p[i].l;j<=n;j+=j&-j)up(T[j],T[j],1,cnt,p[i].r,1);
        }
    }
	return 0;
}
全部评论

相关推荐

找工作勤劳小蜜蜂:自我描述部分太差,完全看不出想从事什么行业什么岗位,也看不出想在哪个地区发展,这样 会让HR很犹豫,从而把你简历否决掉。现在企业都很注重员工稳定性和专注性,特别对于热爱本行业的员工。 你实习的工作又太传统的it开发(老旧),这部分公司已经趋于被淘汰,新兴的互联网服务业,比如物流,电商,新传媒,游戏开发和传统的It开发有天然区别。不是说传统It开发不行,而是就业岗位太少,基本趋于饱和,很多老骨头还能坚持,不需要新血液。 工作区域(比如长三角,珠三角,成渝)等也是HR考虑的因素之一,也是要你有个坚定的决心。否则去几天,人跑了,HR会被用人单位骂死。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务