[Blue Bridge Cup Zhenti]: Compression Transformation

[Blue Bridge Cup Zhenti]: Compression Transformation

text

Topic description

小明最近在研究压缩算法。他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比。然而,要使数值很小是一个挑战。
最近,小明需要压缩一些正整数的序列,这些序列的特点是,后面出现的数字很大可能是刚出现过不久的数字。对于这种特殊的序列,小明准备对序列做一个变换来减小数字的值。
变换的过程如下:
从左到右枚举序列,每枚举到一个数字,如果这个数字没有出现过,刚将数字变换成它的相反数,如果数字出现过,则看它在原序列中最后的一次出现后面(且在当前数前面)出现了几种数字,用这个种类数替换原来的数字。
比如,序列(a1, a2, a3, a4, a5)=(1, 2, 2, 1, 2)在变换过程为:
a1: 1未出现过,所以a1变为-1;
a2: 2未出现过,所以a2变为-2;
a3: 2出现过,最后一次为原序列的a2,在a2后、a3前有0种数字,所以a3变为0;
a4: 1出现过,最后一次为原序列的a1,在a1后、a4前有1种数字,所以a4变为1;
a5: 2出现过,最后一次为原序列的a3,在a3后、a5前有1种数字,所以a5变为1。
现在,给出原序列,请问,按这种变换规则变换后的序列是什么。

input Output

输入格式
输入第一行包含一个整数n,表示序列的长度。第二行包含n个正整数,表示输入序列a。
1 <=n<=1000001<=ai<=10^9
输出格式
对于每组测试数据,输出一行,包含n个数,表示变换后的序列。
输入样例 复制
5
1 2 2 1 2
输出样例 复制
-1 -2 0 1 1

ideas and code

Idea: You only need to perform interval processing between two identical numbers to calculate the result. Note that tree arrays and differential arrays must not be used, and normal results cannot be calculated

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll maxn=1e5+10;
const ll maxm=1e8+10;
const ll mod=1e9+7;
ll n,a[maxn];
struct node{
    
    
    ll l,r,val;
}tr[maxn*4];
map<ll,ll> mt;
void pushup(ll st){
    
    
    tr[st].val=tr[st*2].val+tr[st*2+1].val;
}
void build(ll st,ll l,ll r){
    
    
    tr[st].l=l;
    tr[st].r=r;
    if(l==r){
    
    
        tr[st].val=0;
        return ;
    }
    ll mid=(l+r)>>1;
    build(st*2,l,mid);
    build(st*2+1,mid+1,r);
    pushup(st);
    return ;
}
void update(ll st,ll p,ll val){
    
    
    if(tr[st].l==tr[st].r&&tr[st].l==p){
    
    
        tr[st].val+=val;
        return ;
    }
    ll mid=(tr[st].l+tr[st].r)>>1;
    if(p<=mid){
    
    
        update(st*2,p,val);
    }
    if(p>mid){
    
    
        update(st*2+1,p,val);
    }
    pushup(st);
    return ;
}
ll getsum(ll st,ll l,ll r){
    
    
    if(tr[st].l>=l&&tr[st].r<=r){
    
    
        return tr[st].val;
    }
    ll mid=(tr[st].l+tr[st].r)>>1;
    ll ans=0;
    if(l<=mid){
    
    
        ans+=getsum(st*2,l,r);
    }
    if(mid<r){
    
    
        ans+=getsum(st*2+1,l,r);
    }
    return ans;
}
int main(){
    
    
    scanf("%lld",&n);
    for(int i=1;i<=n;i++){
    
    
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    for(int i=1;i<=n;i++){
    
    
        ll t=a[i];
        if(!mt[t]){
    
    
            a[i]=0-a[i];
            mt[t]=i;
        }else{
    
    
            ll sum=getsum(1,mt[t]+1,i-1);
            update(1,mt[t],-1);
            a[i]=sum;
            mt[t]=i;
        }
        update(1,i,1);
    }
    for(int i=1;i<=n;i++){
    
    
        printf("%lld ",a[i]);
    }

	return 0;
}

Epilogue


"If you are undecided, you can ask the spring breeze, and if the spring breeze does not speak, you will follow your heart" means: if you are hesitant about something, ask the spring breeze how to do it. . "When you are undecided, you can ask the spring breeze, and if the spring breeze does not speak, you will follow your heart." The sentence comes from the "Sword Comes" by the online writer "Fenghuo Opera Princes". The original text is: "If you are undecided, you can ask the spring breeze. Follow your heart".

insert image description here


Guess you like

Origin blog.csdn.net/weixin_46627433/article/details/123604743