日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

luogu P5324 [BJOI2019]删数

發布時間:2025/3/14 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 luogu P5324 [BJOI2019]删数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳送門

不如先考慮暴力,能刪的序列首先有\(1,2,3...n\),還有就是升序排序后從后往前放數,第\(i\)位要么放\(i\),要么放\(i+1\)位置的數,例如\(1,2,4,4,5,6,9,9,9\)

如果一個數\(i\)出現了若干次,假如是\(num_i\)次,我們發現是可以在\(i,i-1,i-2...i-num_i+1\)上放\(i\)的,這樣放完之后,如果有的位置沒有用到現有的數放上去,那么就要從沒用的數里改一個放過來,問題也就是用一堆數,最多能放多少個位置.考慮從后往前放,然后如果一個位置有多個數就接著用這種數往后放.如果放到一個位置\(j\),\(j\)有若干個,當前的\(i\)也有若干個,我們只能用一種放,那么顯然要用更多的那種放.最后沒放數的位置數就是答案.

為了方便,我們把放數看成區間覆蓋,即一個\(i\)可以覆蓋\([i-num_i+1,i]\)這段區間,我們再給所有覆蓋區間加上\(1\),那就是求\([1,n]\)\(0\)的個數.注意到修改的\(+1/-1\)都是整體的,所以如果把所有數放在一根數軸上,那么初始要統計的區間為\([1,n]\),然后整體\(+1\)相當于統計區間整體向左移\(1\),然后 以原統計區間右端點 為右端點 的對應區間覆蓋的貢獻要減掉,因為那個右端點的數超過統計范圍,不能放進來;整體\(-1\)相當于統計區間整體向右移\(1\),然后 以原統計區間右端點 為右端點 的對應區間覆蓋的貢獻要加上;單點修改,也就是原來的\(num_{a_p}\)\(1\),后面的新的\(num\)\(1\),這導致對應兩個覆蓋區間左端點右移和左移.這些東西可以用線段樹維護,注意線段樹的葉子數量應該是\(n+q+q\)

至于區間\(0\)的數量,用值域線段樹維護因為區間\(+1\),某個位置最少為\(0\),只要維護區間最小值及數量就行了

// luogu-judger-enable-o2 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<vector> #include<cmath> #include<ctime> #include<queue> #include<map> #include<set> #define LL long long #define db doubleusing namespace std; const int N=150000+10,M=N*3; int rd() {int x=0,w=1;char ch=0;while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}return x*w; } struct node {int mi,nm;node(){mi=0,nm=1;}node(int nmi,int nnm){mi=nmi,nm=nnm;}node operator + (const node &bb) const{if(mi==bb.mi) return node(mi,nm+bb.nm);return mi<bb.mi?(*this):bb;}void ad(int x){mi+=x;} }s[M<<2],nw; int tg[M<<2]; void psup(int o){s[o]=s[o<<1]+s[o<<1|1];} void psdn(int o){if(tg[o]) s[o<<1].ad(tg[o]),tg[o<<1]+=tg[o],s[o<<1|1].ad(tg[o]),tg[o<<1|1]+=tg[o],tg[o]=0;} #define mid ((l+r)>>1) int nl,nr; void modif(int o,int l,int r,int ll,int rr,int x) {if(ll<=l&&r<=rr){s[o].ad(x),tg[o]+=x;return;}psdn(o);if(ll<=mid) modif(o<<1,l,mid,ll,rr,x);if(rr>mid) modif(o<<1|1,mid+1,r,ll,rr,x);psup(o); } void modif(int lx,int x) {int o=1,l=nl,r=nr,st[21],tp=0;while(l<r){st[++tp]=o,psdn(o);if(lx<=mid) o=o<<1,r=mid;else o=o<<1|1,l=mid+1;}s[o].ad(x);while(tp){o=st[tp--];psup(o);} } node quer(int o,int l,int r,int ll,int rr) {if(ll<=l&&r<=rr) return s[o];psdn(o);node an;an.mi=M;if(ll<=mid) an=an+quer(o<<1,l,mid,ll,rr);if(rr>mid) an=an+quer(o<<1|1,mid+1,r,ll,rr);psup(o);return an; } void bui(int o,int l,int r) {if(l==r) return;bui(o<<1,l,mid),bui(o<<1|1,mid+1,r);psup(o); } int n,q,a[N],nm[M],ll=150001,rr;int main() {n=rd(),q=rd();rr=ll+n-1;nl=ll-q,nr=rr+q;bui(1,nl,nr);for(int i=1;i<=n;++i){a[i]=rd()+ll-1;++nm[a[i]];modif(a[i]-nm[a[i]]+1,1);}while(q--){int p=rd();if(!p){if(~rd()){if(nm[rr]) modif(1,nl,nr,rr-nm[rr]+1,rr,-1);--ll,--rr;}else{++ll,++rr;if(nm[rr]) modif(1,nl,nr,rr-nm[rr]+1,rr,1);}}else{if(a[p]<=rr) modif(a[p]-nm[a[p]]+1,-1);--nm[a[p]];a[p]=rd()+ll-1;++nm[a[p]];modif(a[p]-nm[a[p]]+1,1);}nw=quer(1,nl,nr,ll,rr);printf("%d\n",nw.mi?0:nw.nm);}return 0; }

轉載于:https://www.cnblogs.com/smyjr/p/10770696.html

總結

以上是生活随笔為你收集整理的luogu P5324 [BJOI2019]删数的全部內容,希望文章能夠幫你解決所遇到的問題。

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