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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【线段树】FREQUENT - Frequent values(luogu-SP1684 / poj 3368)

發(fā)布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【线段树】FREQUENT - Frequent values(luogu-SP1684 / poj 3368) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

FREQUENT - Frequent values

luogu-SP1684

poj 3368

題目大意:

有一個單調(diào)不降序列,讓你求出某些區(qū)間內(nèi)的出現(xiàn)次數(shù)最多的數(shù)出現(xiàn)的次數(shù)(有多組數(shù)據(jù),以0結(jié)尾)

輸入樣例

10 3 -1 -1 1 1 1 1 3 10 10 10 2 3 1 10 5 10 0

輸出樣例

1 4 3

數(shù)據(jù)范圍:

1≤n,q≤1000001 ≤ n, q ≤ 1000001n,q100000
?100000≤ai≤100000-100000 ≤ a _{i} ≤ 100000?100000ai?100000

解題思路:

用線段樹,同時要保存左邊數(shù)字出現(xiàn)的次數(shù),和右邊數(shù)字出現(xiàn)的次數(shù),如果中間相等,就可以嘗試拼接

代碼:

#include<cstdio> #include<cstring> #include<iostream> #define max(x,y) (x)>(y)?(x):(y) using namespace std; int n,m,x,y,s[100500]; struct rec {int l,r,num,ls,rs; }tree[800500]; void up(int dep,int mid)//傳遞 {tree[dep].num=max(tree[dep*2].num,tree[dep*2+1].num);tree[dep].ls=tree[dep*2].ls;//ls是左邊的數(shù)出現(xiàn)的次數(shù)tree[dep].rs=tree[dep*2+1].rs;//rs是右邊的數(shù)出現(xiàn)的次數(shù)if (s[mid]==s[mid+1])tree[dep].num=max(tree[dep].num,tree[dep*2].rs+tree[dep*2+1].ls);//如果可以就合并if (s[tree[dep].l]==s[mid+1])tree[dep].ls+=tree[dep*2+1].ls;//同上if (s[mid]==s[tree[dep].r])tree[dep].rs+=tree[dep*2].rs;return; } void make(int dep)//建樹 {if (tree[dep].l==tree[dep].r){tree[dep].num=1;tree[dep].ls=1;tree[dep].rs=1;return;}int mid=(tree[dep].l+tree[dep].r)>>1;tree[dep*2].l=tree[dep].l,tree[dep*2].r=mid;tree[dep*2+1].l=mid+1,tree[dep*2+1].r=tree[dep].r;make(dep*2);make(dep*2+1);up(dep,mid);return; } int find(int dep,int l,int r) {if (tree[dep].l==l&&tree[dep].r==r) return tree[dep].num;if (tree[dep].l>=tree[dep].r) return 0;int mid=(tree[dep].l+tree[dep].r)>>1,sum=1,sum1=1;if (r<=mid) return find(dep*2,l,r);//在左邊if (l>mid) return find(dep*2+1,l,r);//在右邊if (s[mid]==s[mid+1]) sum=min(mid-l+1,tree[dep*2].rs)+min(r-mid,tree[dep*2+1].ls);//合并sum1=max(find(dep*2,l,mid),find(dep*2+1,mid+1,r));//去一個更優(yōu)的return max(sum,sum1);//兩種方法選一種 } int main() {while(scanf("%d",&n),n)//多組數(shù)據(jù){memset(tree,0,sizeof(tree));scanf("%d",&m);for (int i=1;i<=n;++i)scanf("%d",&s[i]);tree[1].l=1;tree[1].r=n;make(1);for (int i=1;i<=m;++i){scanf("%d %d",&x,&y);printf("%d\n",find(1,x,y));}} }

總結(jié)

以上是生活随笔為你收集整理的【线段树】FREQUENT - Frequent values(luogu-SP1684 / poj 3368)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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