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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P3295-[SCOI2016]萌萌哒【ST表,并查集】

發布時間:2023/12/3 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P3295-[SCOI2016]萌萌哒【ST表,并查集】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P3295


題目大意

一個nnn位的數字,mmm個條件給出兩個完全相同的區間,求可能的數字數量。


解題思路

其實就是區間中的每個數字分別連邊,但是這樣顯然會TTT。考慮通過消耗查詢的復雜度來平衡詢問的復雜度。

考慮用STSTST表進行優化,我們定義fi,jf_{i,j}fi,j?的點表示位置[i,i+2j?1][i,i+2^j-1][i,i+2j?1]這個區間,顯然只有jjj相同的可以進行連邊。

連邊完成之后我們按照區間長度從大到小的拆分,對于每個點,我們讓它的兩個下層節點與它父節點的兩個下層節點分開連邊就好了。

時間復雜度O(nlog?n)O(n\log n)O(nlogn)


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e5+10,XJQ=1e9+7; int n,m,cnt,f[N][20],p[N*20],fa[N*20],lg; int find(int x) {return fa[x]==x?(x):(fa[x]=find(fa[x]));} void unionn(int x,int y){x=find(x);y=find(y);if(x==y)return;if(x<y)fa[y]=x;else fa[x]=y;return; } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=0;i+(1<<j)-1<=n;j++)f[i][j]=++cnt,p[cnt]=i,lg=max(lg,j),fa[cnt]=cnt;while(m--){int l1,r1,l2,r2;scanf("%d%d%d%d",&l1,&r1,&l2,&r2);int len=r1-l1+1;for(int i=0;(1<<i)<=len;i++)if((len>>i)&1)unionn(f[l1][i],f[l2][i]),l1+=(1<<i),l2+=(1<<i);}for(int j=lg;j>=1;j--)for(int i=1;i+(1<<j)-1<=n;i++){int x=f[i][j],y=find(x);if(x==y)continue;int ii=p[y];unionn(f[i][j-1],f[ii][j-1]);unionn(f[i+(1<<j-1)][j-1],f[ii+(1<<j-1)][j-1]);}int ans=1;bool flag=1;for(int i=1;i<=n;i++)if(p[find(f[i][0])]==i){if(flag)ans=9,flag=0;else ans=1ll*ans*10%XJQ;}printf("%d\n",ans); }

總結

以上是生活随笔為你收集整理的P3295-[SCOI2016]萌萌哒【ST表,并查集】的全部內容,希望文章能夠幫你解決所遇到的問題。

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