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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

SPOJ - DQUERY D-query(莫队/线段树+离线/主席树)

發(fā)布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SPOJ - DQUERY D-query(莫队/线段树+离线/主席树) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出一個由n個數組成的序列,再給出m次查詢,每次查詢區(qū)間[l,r]中有多少個不同的數

題目分析:莫隊模板題,直接套板子就好了

有點意思的是函數返回值為布爾類型,然后沒有return的話就會RE,神仙評測機

或者也可以用線段樹離線做,按照區(qū)間右端點排序,每次維護一下某個數值最后一次出現(xiàn)的位置,實時更新其最后出現(xiàn)的位置,保證某個數值在線段樹中只出現(xiàn)一次即可

2020.6.20更新:

主席樹模板題,原理和線段樹離線差不多,主席樹的每個版本維護的是 [ 1 , i ] 中每個數字出現(xiàn)的最后位置,這樣查詢 [ l , r ] 內的答案就是查詢第 r 個版本的主席樹中 [ l , r ] 的 sum 了

2020.10.8更新:

又發(fā)現(xiàn)了一種主席樹的寫法,相對于上面的那一種,思維點更巧妙,且能節(jié)省一倍的空間,具體實現(xiàn)如下:

  • 初始化所有的 pre[ i ] = 0,其意義為數字 i 前一次出現(xiàn)的位置
  • 對于每個 a[ i ] 來說,將 pre[ a[ i ]?] 插入到主席樹的 root[ i ] 的位置 i 中
  • 查詢 [ l , r ] 區(qū)間內不同數的個數,就相當于查詢 [ l , r ] 內有有多少個 i 滿足 pre[ a[ i ]?] < l
  • 換句話說就是需要查詢 root[ l?] ~ root[ r ] 的權值線段樹中,[ 0 , l - 1 ] 內有多少個數
  • 代碼:

    莫隊:

    #include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=2e5+100;const int M=1e6+100;int size,n,m,ans[N],a[N];int vis[M];struct query {int l,r,id;bool operator<(const query a)const{if(l/size!=a.l/size)return l/size<a.l/size;return r<a.r;} }q[N];int del(int pos) {vis[a[pos]]--;if(vis[a[pos]]==0)return -1;return 0; }int add(int pos) {vis[a[pos]]++;if(vis[a[pos]]==1)return 1;return 0; }void solve() {int l=1,r=0;int sum=0;for(int i=1;i<=m;i++){int ql=q[i].l;int qr=q[i].r;while(l<ql)sum+=del(l++);while(l>ql)sum+=add(--l);while(r<qr)sum+=add(++r);while(r>qr)sum+=del(r--);ans[q[i].id]=sum;} }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);scanf("%d",&n);size=sqrt(n);for(int i=1;i<=n;i++)scanf("%d",a+i);scanf("%d",&m);for(int i=1;i<=m;i++){scanf("%d%d",&q[i].l,&q[i].r);q[i].id=i;}sort(q+1,q+1+m);solve();for(int i=1;i<=m;i++)printf("%d\n",ans[i]);return 0; }

    線段樹:

    #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<sstream> #include<cmath> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=3e4+100;struct Node {int l,r;int sum; }tree[N<<2];//簡單的維護sum和的線段樹int a[N];int ans[200100];int vis[1000100];struct node {int x,y,id;bool operator<(node a)const{return y<a.y;} }pos[200100];void build(int k,int l,int r) {tree[k].l=l;tree[k].r=r;tree[k].sum=0;if(l==r)return;int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r); }void update(int k,int pos,int val) {if(tree[k].l==tree[k].r){tree[k].sum=val;return;}int mid=(tree[k].l+tree[k].r)>>1;if(mid>=pos)update(k<<1,pos,val);elseupdate(k<<1|1,pos,val);tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; }int query(int k,int l,int r) {if(tree[k].r<l||tree[k].l>r)return 0;if(tree[k].r<=r&&tree[k].l>=l)return tree[k].sum;return query(k<<1,l,r)+query(k<<1|1,l,r); }int main() { // freopen("input.txt","r",stdin);int n,m;while(scanf("%d",&n)!=EOF){memset(vis,0,sizeof(vis));build(1,1,n);for(int i=1;i<=n;i++)scanf("%d",a+i);int m;scanf("%d",&m);for(int i=1;i<=m;i++){scanf("%d%d",&pos[i].x,&pos[i].y);pos[i].id=i;}sort(pos+1,pos+1+m);int t=1;for(int i=1;i<=m;i++){while(t<=pos[i].y){if(vis[a[t]])//該數字如果之前出現(xiàn)過update(1,vis[a[t]],0);//刪掉原來的位置vis[a[t]]=t;//更新當前位置update(1,vis[a[t]],1);//線段樹一并更新t++;}ans[pos[i].id]=query(1,pos[i].x,pos[i].y);}for(int i=1;i<=m;i++)printf("%d\n",ans[i]);}return 0; }

    主席樹:
    ?

    #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> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;const int M=1e6+100;int a[N],pre[M];struct Node {int l,r;int sum; }tree[N*40];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) {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("input.txt","r",stdin); // freopen("output.txt","w",stdout); #endif // ios::sync_with_stdio(false);init();int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",a+i);for(int i=1;i<=n;i++){root[i]=root[i-1];if(pre[a[i]])update(pre[a[i]],root[i],1,n,-1);update(i,root[i],1,n,1);pre[a[i]]=i;}int m;scanf("%d",&m);while(m--){int l,r;scanf("%d%d",&l,&r);printf("%d\n",query(root[r],l,r,1,n));}return 0; }

    主席樹2:

    //#pragma GCC optimize(2) //#pragma GCC optimize("Ofast","inline","-ffast-math") //#pragma GCC target("avx,sse2,sse3,sse4,mmx") #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<list> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;const int M=1e6+100;int a[N],pre[M];struct Node {int l,r;int sum; }tree[N*20];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) {tree[cnt++]=tree[k];k=cnt-1;tree[k].sum++;if(l==r)return;int mid=l+r>>1;if(pos<=mid)update(pos,tree[k].l,l,mid);elseupdate(pos,tree[k].r,mid+1,r); }int query(int i,int j,int l,int r,int L,int R)//[l,r]:目標區(qū)間,[L,R]:當前區(qū)間 {if(R<l||L>r)return 0;if(L>=l&&R<=r)return tree[i].sum-tree[j].sum;int mid=L+R>>1;return query(tree[i].l,tree[j].l,l,r,L,mid)+query(tree[i].r,tree[j].r,l,r,mid+1,R); }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.ans.txt","w",stdout); #endif // ios::sync_with_stdio(false);init();int n;scanf("%d",&n);for(int i=1;i<=n;i++){int num;scanf("%d",&num);root[i]=root[i-1];update(pre[num],root[i],0,n);pre[num]=i;}int m;scanf("%d",&m);while(m--){int l,r;scanf("%d%d",&l,&r);printf("%d\n",query(root[r],root[l-1],0,l-1,0,n));}return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的SPOJ - DQUERY D-query(莫队/线段树+离线/主席树)的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 波多野结av衣东京热无码专区 | 天堂一区在线观看 | av播播| 91蜜桃网站| a级片免费视频 | 九九热超碰 | 男人爽女人下面动态图 | 美女隐私无遮挡网站 | 日本高清免费aaaaa大片视频 | 中文字幕一区二区人妻痴汉电车 | 性欧美精品中出 | 欧美一区二区三区视频在线观看 | 欧美性爱精品在线 | 欧美乱大交xxxxx潮喷 | 国产日产精品一区二区 | 国产第五页 | 成年女人毛片 | 中文在线观看av | 国产aⅴ精品一区二区三区久久 | 人妻熟人中文字幕一区二区 | 一级片在线免费播放 | 成人黄色激情视频 | 成人在线综合网 | 国产精品国产一区 | 99热这里只有精品66 | 久草精品在线 | 中文字幕在线一区二区三区 | 日韩精品欧美精品 | 日韩综合av | 日韩成人免费在线视频 | wwwxx欧美| 碰碰久久 | 青青草黄色 | 91动态图 | 久久天堂av | 国产欧美精品国产国产专区 | www.youjizz日本 | 日日操日日 | 丁香婷婷在线 | av一区不卡 | 成人在线观看免费 | 国产特级av | 午夜一区二区三区四区 | 中文国语毛片高清视频 | 色在线综合 | 黑人巨大精品欧美一区免费视频 | 人与性动交zzzzbbbb | 污污视频网站免费观看 | 欧美一级片在线播放 | 亚洲性视频在线 | 欧美三级一级片 | 日批在线观看 | 网站色 | 色花堂在线 | 欧美日韩亚洲国产综合 | 成人精品一区二区 | 我要看免费毛片 | 久久精品一二三 | 神马午夜av | 国产福利91精品一区二区三区 | 日本一区视频在线播放 | 亚洲精品天堂成人片av在线播放 | 亚洲中文字幕久久无码 | 99精品视频国产 | 亚洲一区有码 | 老湿福利影院 | 亚洲免费黄色 | 久久99热久久99精品 | 色老汉av一区二区三区 | 少妇高清精品毛片在线视频 | 日本大尺度吃奶做爰久久久绯色 | 久久综合免费 | 一本色道久久综合亚洲精品按摩 | 国产一级做a爰片在线看免费 | 成人hd | 边添小泬边狠狠躁视频 | 色片网站在线观看 | 成人免费看片在线观看 | 一级激情片 | 人人澡人人射 | 熟女人妻视频 | 精品aaa | 亚洲欧美日韩国产精品 | 男人操女人免费 | 91久久电影 | 欧美特级黄色录像 | 中文字幕免费看 | 国产成人无码精品亚洲 | 成人精品 | 国产精品成人久久久 | 99热青青草 | 在线无码va中文字幕无码 | 手机av中文字幕 | 农村寡妇一区二区三区 | 亚洲综合久久久 | 久久发布国产伦子伦精品 | 免费看黄在线 | 国产一区精品在线观看 | 99激情|