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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

牛客多校5 - Interval(主席树)

發布時間:2024/4/11 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客多校5 - Interval(主席树) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出一個長度為 n 的數列 a ,規定函數 f( l , r ) = a[ l ] & a[ l + 1 ] & ... & a[ r ] ,在規定set?s( l , r ) = { f( a , b ) | l <= a <= b <= r } ,對于 q 次詢問,每次詢問回答 s( l , r )

題目分析:根據位運算的性質,可以知道每一位都是相互獨立的,再根據與運算的性質,可以知道,當左端點或者右端點的其中一個端點在固定之后,不同的 f( l , r ) 最多有 logn 個,因為假設當前端點二進制下全部為 1 ,因為 f 函數是需要取連續的一段子數列,所以每次減少一個 1 ,最多減少 logn 次在二進制下就變為 0 了

假設數列為 a[ 1 ] , a[ 2 ] , a[ 3 ] ... a[ n - 1 ] , a[ n ] ,對于一個位置 i 來說,記錄其全部的后綴,也就是:

  • a[ 1 ] & a[ 2 ] & ... & a[ i - 1 ] & a[ i ]
  • a[ 2 ] & a[ 3 ] & ... & a[ i - 1?] & a[ i ]
  • a[ 3 ] & a[ 4 ] & ... & a[ i - 1 ] & a[ i ]
  • ......
  • a[ i - 1 ] & a[ i ]
  • a[ i ]
  • 雖然一共有 i 個后綴,但根據上一段分析的性質,當固定了右端點 i 后,最多只會有 logn 個不同的數字

    到此為止,剩下的就可以用主席樹統計區間有多少個不同的數字的那個模板來實現了

    代碼:

    #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;unordered_map<int,int>mp,temp,pre;struct Node {int l,r;int sum; }tree[N*150];int cnt,root[N];void init() {root[0]=0;tree[0].l=tree[0].r=tree[0].sum=0;cnt=1; }void update(int pos,int &k,int l,int r,int val) {tree[cnt++]=tree[k];k=cnt-1;tree[k].sum+=val;if(l==r)return;int mid=l+r>>1;if(pos<=mid)update(pos,tree[k].l,l,mid,val);elseupdate(pos,tree[k].r,mid+1,r,val); }int query(int rt,int l,int r,int L,int R)//[l,r]:目標區間,[L,R]:當前區間 {if(R<l||L>r)return 0;if(L>=l&&R<=r)return tree[rt].sum;int mid=L+R>>1;return query(tree[rt].l,l,r,L,mid)+query(tree[rt].r,l,r,mid+1,R); }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);init();int n;scanf("%d",&n);for(int i=1;i<=n;i++){root[i]=root[i-1];int x;scanf("%d",&x);mp[x]=i;temp.clear();for(auto it=mp.begin();it!=mp.end();it++){int fir=it->first,sec=it->second;temp[x&fir]=max(temp[x&fir],sec);}for(auto it=temp.begin();it!=temp.end();it++){int fir=it->first,sec=it->second;if(pre[fir])update(pre[fir],root[i],1,n,-1);pre[fir]=sec;update(pre[fir],root[i],1,n,1);}mp=temp;}int q,ans=0;scanf("%d",&q);while(q--){int l,r;scanf("%d%d",&l,&r);l=(l^ans)%n+1;r=(r^ans)%n+1;if(l>r)swap(l,r);printf("%d\n",ans=query(root[r],l,r,1,n));}return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的牛客多校5 - Interval(主席树)的全部內容,希望文章能夠幫你解決所遇到的問題。

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