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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

mex性质学习

發(fā)布時(shí)間:2023/12/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mex性质学习 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

E.Complicated Computations

如果一個(gè)區(qū)間的mex=amex=amex=a,滿足以下條件:

  • 區(qū)間未出現(xiàn)aaa
  • 區(qū)間出現(xiàn)1→a?11\to a-11a?1

因此若考慮是否存在一個(gè)區(qū)間的mex值是aaa,我們嘗試把整個(gè)區(qū)間以aaa為端點(diǎn)劃分成若干段,只要每一段內(nèi)(不含端點(diǎn)a)中出現(xiàn)1→a?11\to a-11a?1那么就存在一個(gè)區(qū)間的mex值是aaa
a…a…a…a…a…a…aa\dots a\dots a\dots a\dots a\dots a\dots aaaaaaaa
即只要有一個(gè)…\dots存在1→a?11\to a-11a?1那么就存在區(qū)間mex=amex=amex=a

那么如何確定…\dots存在1→a?11\to a-11a?1
不妨假設(shè)兩個(gè)a的位置一個(gè)是LLL,一個(gè)是RRR,那么我們現(xiàn)在判定[L+1,R?1][L+1,R-1][L+1,R?1]的區(qū)間是否存在1→a?11\to a-11a?1。那么不難發(fā)現(xiàn)1→a?11\to a-11a?1最后一次出現(xiàn)的位置>L>L>L
由此用權(quán)值線段樹維護(hù)每一個(gè)數(shù)最后一次出現(xiàn)的位置,并且記錄上一次某數(shù)出現(xiàn)的位置查詢即可。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<random> #include<bitset> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> #include<unordered_set> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int mod=1e9+7; const int N=100010; int a[N],n; bool st[N]; int last[N]; int pos[N<<2]; void modify(int u,int l,int r,int k,int x) {if(l==r) {pos[u]=x;return;}int mid=l+r>>1;if(k<=mid) modify(u<<1,l,mid,k,x);else modify(u<<1|1,mid+1,r,k,x);pos[u]=min(pos[u<<1],pos[u<<1|1]); } int query(int u,int l,int r,int L,int R) {if(l>=L&&r<=R) return pos[u];int mid=l+r>>1;if(R<=mid)return query(u<<1,l,mid,L,R);else if(L>mid)return query(u<<1|1,mid+1,r,L,R);else return min(query(u<<1,l,mid,L,R),query(u<<1|1,mid+1,r,L,R)); } int main() {IO;int T=1;//cin>>T;for(int ca=1;ca<=T;ca++){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++){if(a[i]!=1) st[1]=1;if(a[i]>1&&query(1,1,n,1,a[i]-1)>last[a[i]]) st[a[i]]=1;last[a[i]]=i;modify(1,1,n,a[i],i);}for(int i=2;i<=n+1;i++) //枚舉到n+1有可能有區(qū)間的mex=n+1if(query(1,1,n,1,i-1)>last[i]) st[i]=1;int res=1;while(st[res]) res++;cout<<res<<'\n';}return 0; }

這題竟然還卡時(shí)間?用build版本的線段樹就TLE,只能查詢時(shí)傳遞區(qū)間。。。

Hdu. Mex

大佬題解
mex(1,i)mex(1,i)mex(1,i)具有單調(diào)遞增的性質(zhì)。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<random> #include<bitset> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> #include<unordered_set> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int mod=1e9+7; const int N=200010; int a[N],n; int mex[N],ne[N],pos[N]; bool st[N]; struct node {int l,r;ll s;ll lazy; }tree[N<<2]; void pushup(int u) {tree[u].s=tree[u<<1].s+tree[u<<1|1].s; } void build(int u,int l,int r) {tree[u]={l,r,0,-1};if(l==r){tree[u].s=mex[l]; return;}int mid=l+r>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u); } void pushdown(int u) {if(tree[u].lazy==-1) return;int lenl=tree[u<<1].r-tree[u<<1].l+1;int lenr=tree[u<<1|1].r-tree[u<<1|1].l+1;tree[u<<1].s=1ll*lenl*tree[u].lazy;tree[u<<1|1].s=1ll*lenr*tree[u].lazy;tree[u<<1].lazy=tree[u].lazy;tree[u<<1|1].lazy=tree[u].lazy;tree[u].lazy=-1; } void modify(int u,int l,int r,int x) {if(tree[u].l>=l&&tree[u].r<=r){tree[u].s=1ll*x*(tree[u].r-tree[u].l+1);tree[u].lazy=x;return;}pushdown(u);int mid=tree[u].l+tree[u].r>>1;if(l<=mid) modify(u<<1,l,r,x);if(r>mid) modify(u<<1|1,l,r,x);pushup(u); } ll query(int u,int l,int r) {if(tree[u].l>=l&&tree[u].r<=r) return tree[u].s;pushdown(u);int mid=tree[u].l+tree[u].r>>1;ll v=0;if(l<=mid) v+=query(u<<1,l,r);if(r>mid) v+=query(u<<1|1,l,r);return v; } int main() {while(scanf("%d",&n),n){for(int i=1;i<=n;i++){scanf("%d",&a[i]);if(a[i]>n) a[i]=n+1;}for(int i=0;i<=n+1;i++) st[i]=0;int now=0;for(int i=1;i<=n;i++){st[a[i]]=1;while(st[now]) now++;mex[i]=now;}for(int i=0;i<=n+1;i++) pos[i]=n+1;for(int i=n;i;i--){ne[i]=pos[a[i]];pos[a[i]]=i;}build(1,1,n);ll res=0;for(int i=1;i<=n;i++){res+=query(1,i,n);int l=i,r=ne[i]-1;while(l<r){int mid=l+r>>1;if(query(1,mid,mid)>a[i]) r=mid;else l=mid+1;}if(query(1,l,l)>a[i]) modify(1,l,ne[i]-1,a[i]);}printf("%lld\n",res);}return 0; }

總結(jié)

以上是生活随笔為你收集整理的mex性质学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。