日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

[蓝桥杯][2016年第七届真题]压缩变换(主席树求区间不同数的个数)

發布時間:2023/12/15 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [蓝桥杯][2016年第七届真题]压缩变换(主席树求区间不同数的个数) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述
小明最近在研究壓縮算法。
他知道,壓縮的時候如果能夠使得數值很小,就能通過熵編碼得到較高的壓縮比。
然而,要使數值很小是一個挑戰。

最近,小明需要壓縮一些正整數的序列,這些序列的特點是,后面出現的數字很大可能是剛出現過不久的數字。對于這種特殊的序列,小明準備對序列做一個變換來減小數字的值。

變換的過程如下:
從左到右枚舉序列,每枚舉到一個數字,如果這個數字沒有出現過,剛將數字變換成它的相反數,如果數字出現過,則看它在原序列中最后的一次出現后面(且在當前數前面)出現了幾種數字,用這個種類數替換原來的數字。

比如,序列(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。
現在,給出原序列,請問,按這種變換規則變換后的序列是什么。
輸入
輸入第一行包含一個整數n,表示序列的長度。
第二行包含n個正整數,表示輸入序列。
輸出
輸出一行,包含n個數,表示變換后的序列。
樣例輸入
5
1 2 2 1 2
樣例輸出
-1 -2 0 1 1
思路:這個題目我不知道有沒有別的做法,但是主席樹是可以做的。這算是一個求區間不同數的個數的模板題了。注意區間端點的取值。
代碼如下:

#include<bits/stdc++.h> #define ll long long using namespace std;const int maxx=1e5+100; struct node{int l,r,sum; }p[maxx*40]; int root[maxx*40]; int a[maxx]; int n,rot=0;inline int build(int l,int r) {int cur=++rot;p[cur].sum=0;p[cur].l=p[cur].r=0;if(l==r) return cur;int mid=l+r>>1;p[cur].l=build(l,mid);p[cur].r=build(mid+1,r);return cur; } inline int update(int pos,int lrot,int v,int l,int r) {int cur=++rot;p[cur]=p[lrot];p[cur].sum+=v;if(l==r) return cur;int mid=l+r>>1;if(pos<=mid) p[cur].l=update(pos,p[lrot].l,v,l,mid);else p[cur].r=update(pos,p[lrot].r,v,mid+1,r);return cur; } inline int query(int pos,int lrot,int l,int r) {if(l==r) return p[lrot].sum;int mid=l+r>>1;if(pos<=mid) return p[p[lrot].r].sum+query(pos,p[lrot].l,l,mid);else return query(pos,p[lrot].r,mid+1,r); } int main() {scanf("%d",&n);map<int,int> mp;for(int i=1;i<=n;i++) scanf("%d",&a[i]);root[0]=build(1,n);for(int i=1;i<=n;i++){if(mp[a[i]]==0) root[i]=update(i,root[i-1],1,1,n);else{int t=update(mp[a[i]],root[i-1],-1,1,n);root[i]=update(i,t,1,1,n);}mp[a[i]]=i;}mp.clear();for(int i=1;i<=n;i++){if(mp[a[i]]==0) cout<<-a[i]<<" ";else cout<<query(mp[a[i]]+1,root[i-1],1,n)<<" ";mp[a[i]]=i;}return 0; }

努力加油a啊,(o)/~

總結

以上是生活随笔為你收集整理的[蓝桥杯][2016年第七届真题]压缩变换(主席树求区间不同数的个数)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。