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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

bzoj 3685

發布時間:2025/7/25 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj 3685 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線段樹

方法一:

值域線段樹,遞歸去寫的,每次節點存出現次數.

對于幾個操作, 1,2 直接加減就好 ; 3,4 操作貪心往某一個方向找 .7也很簡單,主要說前驅后繼怎么找。我是先找這個數第幾小,根據相應關系得出我們需要輸出第幾小。然后就寫了一下 TLE。詳見代碼一;

解決辦法

加入輸入外掛 .... 過了.詳見代碼二。

方法二:

參考了zkw,原來就是遞歸改為循環,再用到滿二叉樹性質.有些能夠O(1) 求出.

具體做法:先確定范圍,讓二叉樹最后一層節點數>=n.并找到最后一層節點編號 L-R .和前面有sz個節點. 增刪我們從 sz+x這個節點開始加上一個數,之后除以2.
再寫一個查詢最大最小.那個函數傳入的是節點編號.所以他可以查詢某個子樹的max,min.結合到前驅后繼。比如查詢x前驅,我就從x那個最底層點開始,看我是右兒子?如果是,看左兒子節點有數?有查詢那顆子樹的max,即為答案,反之也是一樣的。最后一個操作直接來。sz+x。對于下標處理原題 [0,n-1] . 線段樹 是1開始所以減一莫要忘記.
具體寫法,參考代碼三。

//代碼一 #include <stdio.h>const int maxn=1e6+10;int T[maxn*4]; void ins(int i,int l,int r,int x,int val)// 1 2 {if(l==r) {T[i]=val;return ;}int mid=(l+r)>>1;if(x<=mid) ins(i<<1,l,mid,x,val);else ins(i<<1|1,mid+1,r,x,val);T[i]=T[i<<1]+T[i<<1|1]; } int fmax(int i,int l,int r) {if(T[i]==0) return -1;if(l==r) return l;int mid=(l+r)>>1;if(T[i<<1|1]) return fmax(i<<1|1,mid+1,r);else return fmax(i<<1,l,mid); } int fmin(int i,int l,int r) {if(T[i]==0) return -1;if(l==r) return l;int mid=(l+r)>>1;if(T[i<<1]) return fmin(i<<1,l,mid);else return fmin(i<<1|1,mid+1,r); }int fx(int i,int l,int r,int x) {if(l==r) return T[i]?1:-1;int mid=(l+r)>>1;if(x<=mid) return fx(i<<1,l,mid,x);else return fx(i<<1|1,mid+1,r,x); }bool flag; int kth(int i,int l,int r,int x) {if(l==r) {flag=T[i];return T[i];}int mid=(l+r)>>1;if(x<=mid) return kth(i<<1,l,mid,x);else return T[i<<1]+kth(i<<1|1,mid+1,r,x); }int fkth(int i,int l,int r,int k) {if(l==r) {if(T[i]) return l;else return -1;}int mid=(l+r)>>1;int sum=T[i<<1];if(sum>=k) return fkth(i<<1,l,mid,k);else return fkth(i<<1|1,mid+1,r,k-sum); }int main() {int n,m;scanf("%d%d",&n,&m);while(m--){int op,x;scanf("%d",&op);if(op==3||op==4) ;else scanf("%d",&x);if(op==1) ins(1,-1,n+1,x,1);else if(op==2) ins(1,-1,n+1,x,0);else if(op==3) printf("%d\n",fmin(1,-1,n+1));else if(op==4) printf("%d\n",fmax(1,-1,n+1));else if(op==5){int k=kth(1,-1,n+1,x);//printf("k=%d flag=%d\n",k,flag?1:0);if(flag) k--;printf("%d\n",fkth(1,-1,n+1,k));}else if(op==6){int k=kth(1,-1,n+1,x);k++;printf("%d\n",fkth(1,-1,n+1,k));}else printf("%d\n",fx(1,-1,n+1,x));}return 0; }/*10 100 1 2 1 4 1 6 1 8 1 10*/ //代碼二 #include <stdio.h>const int maxn=1e6+10; inline char nc() {static char buf[100000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int sc() {char ch=nc();int sum=0;while(!(ch>='0'&&ch<='9'))ch=nc();while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();return sum; }int T[maxn*4]; void ins(int i,int l,int r,int x,int val)// 1 2 {if(l==r) {T[i]=val;return ;}int mid=(l+r)>>1;if(x<=mid) ins(i<<1,l,mid,x,val);else ins(i<<1|1,mid+1,r,x,val);T[i]=T[i<<1]+T[i<<1|1]; } int fmax(int i,int l,int r) {if(T[i]==0) return -1;if(l==r) return l;int mid=(l+r)>>1;if(T[i<<1|1]) return fmax(i<<1|1,mid+1,r);else return fmax(i<<1,l,mid); } int fmin(int i,int l,int r) {if(T[i]==0) return -1;if(l==r) return l;int mid=(l+r)>>1;if(T[i<<1]) return fmin(i<<1,l,mid);else return fmin(i<<1|1,mid+1,r); }int fx(int i,int l,int r,int x) {if(l==r) return T[i]?1:-1;int mid=(l+r)>>1;if(x<=mid) return fx(i<<1,l,mid,x);else return fx(i<<1|1,mid+1,r,x); }bool flag; int kth(int i,int l,int r,int x) {if(l==r) {flag=T[i];return T[i];}int mid=(l+r)>>1;if(x<=mid) return kth(i<<1,l,mid,x);else return T[i<<1]+kth(i<<1|1,mid+1,r,x); }int fkth(int i,int l,int r,int k) {if(l==r) {if(T[i]) return l;else return -1;}int mid=(l+r)>>1;int sum=T[i<<1];if(sum>=k) return fkth(i<<1,l,mid,k);else return fkth(i<<1|1,mid+1,r,k-sum); }int main() {int n,m;scanf("%d%d",&n,&m);while(m--){int op,x;op=sc();if(op==3||op==4) ;else x=sc();if(op==1) ins(1,-1,n+1,x,1);else if(op==2) ins(1,-1,n+1,x,0);else if(op==3) printf("%d\n",fmin(1,-1,n+1));else if(op==4) printf("%d\n",fmax(1,-1,n+1));else if(op==5){int k=kth(1,-1,n+1,x);//printf("k=%d flag=%d\n",k,flag?1:0);if(flag) k--;printf("%d\n",fkth(1,-1,n+1,k));}else if(op==6){int k=kth(1,-1,n+1,x);k++;printf("%d\n",fkth(1,-1,n+1,k));}else printf("%d\n",fx(1,-1,n+1,x));}return 0; }/*10 100 1 2 1 4 1 6 1 8 1 10*/ //代碼三 #include <stdio.h> #include <stdlib.h> #include <algorithm> const int maxn=1e6+10; int T[maxn*4],sz,L,R; void ins(int i,int val) {i=i+sz;if(T[i]==1&&val==1) return ;if(T[i]==0&&val==-1) return ;for(;i>0;i>>=1) T[i]+=val; } int fmax(int i) {if(T[i]==0) return 0;while(i<=sz){if(T[i<<1|1]) i=i<<1|1;else i=i<<1;}return i-sz; } int fmin(int i) {if(T[i]==0) return 0;while(i<=sz){if(T[i<<1]) i=i<<1;else i=i<<1|1;}return i-sz; } int fpre(int i) {i=i+sz;for(;i!=1;i>>=1)if((i&1)&&T[i^1]) return fmax(i^1);return 0; } int fsuc(int i) {i=i+sz;for(;i!=1;i>>=1)if(!(i&1)&&T[i^1]) return fmin(i^1);return 0; } int main() {int n,m;scanf("%d%d",&n,&m);sz=0;for(int i=1;i<n;i=(i<<1)){sz+=i;L=sz+1;R=sz+(i<<1);}while(m--){int op,x;scanf("%d",&op);if(op==3||op==4);else scanf("%d",&x);x++;if(op==1) ins(x,1);else if(op==2) ins(x,-1);else if(op==3) printf("%d\n",fmin(1)-1);else if(op==4) printf("%d\n",fmax(1)-1);else if(op==5) printf("%d\n",fpre(x)-1);else if(op==6) printf("%d\n",fsuc(x)-1);else printf("%d\n",T[sz+x]?1:-1);}return 0; }

轉載于:https://www.cnblogs.com/coded-ream/p/7522087.html

總結

以上是生活随笔為你收集整理的bzoj 3685的全部內容,希望文章能夠幫你解決所遇到的問題。

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