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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

牛客 - 牛半仙的妹子图(并查集+bitset/克鲁斯卡尔重构树+主席树)

發(fā)布時間:2024/4/11 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客 - 牛半仙的妹子图(并查集+bitset/克鲁斯卡尔重构树+主席树) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出一個由 n 個點和 m 條邊組成的連通圖,每個點都有一種顏色,每條邊都有一個權(quán)值,現(xiàn)在規(guī)定一個起點 st,再給出 q 次詢問,每次詢問給出區(qū)間 [ l , r ] ,問權(quán)值為?i ∈ [ l , r ] 時,從起點經(jīng)過權(quán)值不超過 i 的連通塊內(nèi),有多少種不同的顏色

題目分析:因為需要回答的答案滿足前綴和的性質(zhì),所以可以預(yù)處理出前綴和然后 O( 1 ) 回答,但是詢問的范圍特別大, 需要對前綴和進(jìn)行離散化,這個應(yīng)該算是一個小技巧,具體實現(xiàn)可以參考代碼

然后就是顏色的種類數(shù)非常小,所以可以對每個點維護(hù)一個 bitset 用來記錄顏色,然后對邊權(quán)進(jìn)行排序后,并查集合并 bitset 就好了,每次維護(hù)起點 st 所在的連通塊內(nèi)的顏色數(shù)即可,這樣還可以實時維護(hù)前綴和

上述做法預(yù)處理的時間復(fù)雜度為 O( k * 600 * n / 32 ),k 為并查集的常數(shù),查詢是 O( qlogn ),因為需要進(jìn)行一次二分,所以總時間復(fù)雜度就是 O( k * 600 * n / 32 + qlogn ),約等于 1e7

但如果顏色的種類數(shù)繼續(xù)變大該怎么辦呢,如果 C 的取值范圍改成小于等于 1e9 ,肯定是沒法用 bitset 來維護(hù)了

所以考慮另一種做法,在預(yù)處理前綴和的時候,實質(zhì)上是需要求解 “ 經(jīng)過邊權(quán)不大于 x 的連通塊內(nèi)有多少種不同的顏色?”,分開來看,前半句說的是克魯斯卡爾重構(gòu)樹,而后半句說的就是主席樹了,很自然的可以想到先離線下來構(gòu)建重構(gòu)樹,然后對于 st 所在的節(jié)點,一直向上跳 father 即可,每次到達(dá)一個新的 father ,其子樹就代表著一個新的連通塊,用主席樹實時查詢有多少種不同的顏色,同上維護(hù)前綴和就好了,因為主席樹是動態(tài)開點的,所以自然可以動態(tài)離散化,C 的范圍再大也不是問題了

代碼:

并查集+bitset

//#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> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=5e5+100;struct Edge {int u,v,w;bool operator<(const Edge& t)const{return w<t.w;}void input(){scanf("%d%d%d",&u,&v,&w);} }edge[N];bitset<610>color[N];int f[N];LL sum[N],cnt[N],t[N];int find(int x) {return f[x]==x?x:f[x]=find(f[x]); }void merge(int x,int y)//x->y {int xx=find(x),yy=find(y);if(xx!=yy){f[xx]=yy;color[yy]|=color[xx];} }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int n,m,q,st,opt,p;scanf("%d%d%d%d%d",&n,&m,&q,&st,&opt);if(opt)scanf("%d",&p);for(int i=1;i<=n;i++){f[i]=i;int x;scanf("%d",&x);color[i][x]=true;}for(int i=1;i<=m;i++)edge[i].input();sort(edge+1,edge+1+m);for(int i=1;i<=m;i++){int xx=find(edge[i].u),yy=find(edge[i].v);if(xx==st)merge(edge[i].v,edge[i].u);elsemerge(edge[i].u,edge[i].v);cnt[i]=color[st].count();t[i]=edge[i].w;}cnt[0]=1;t[0]=0;for(int i=1;i<=m;i++)sum[i]=sum[i-1]+cnt[i-1]*(t[i]-t[i-1]-1)+cnt[i];LL last=0;while(q--){int l,r;scanf("%d%d",&l,&r);if(opt){l=(l^last)%p+1;r=(r^last)%p+1;if(l>r)swap(l,r);}l--;int ll=upper_bound(t+1,t+1+m,l)-t-1;int rr=upper_bound(t+1,t+1+m,r)-t-1;LL ans=(sum[rr]+(r-t[rr])*cnt[rr])-(sum[ll]+(l-t[ll])*cnt[ll]);printf("%lld\n",last=ans);}return 0; }

克魯斯卡爾重構(gòu)樹+主席樹

//#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> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e6+100;LL sum[N],cnt[N],t[N],pre[N],c[N]; /*克魯斯卡爾重構(gòu)樹*/ struct Ex_Kruskal {struct Edge{int x,y,w;bool operator<(const Edge& t)const{return w<t.w;}}edge[N];int f[N],L[N],R[N],val[N],id[N],fa[N],tot,index,cnt,n;vector<int>node[N];void init(int n){cnt=tot=0;index=n;for(int i=0;i<=n<<1;i++){f[i]=i;node[i].clear();}}int find(int x){return f[x]==x?x:f[x]=find(f[x]);}void addedge(int x,int y,int w){edge[++cnt]={x,y,w};}void solve(){sort(edge+1,edge+1+cnt);for(int i=1;i<=cnt;i++){int xx=find(edge[i].x),yy=find(edge[i].y);if(xx!=yy){f[xx]=f[yy]=++index;node[index].push_back(xx);node[index].push_back(yy);val[index]=edge[i].w;}}n=index;for(int i=1;i<=n;i++)if(find(i)==i)dfs(i,0);}void dfs(int u,int f){L[u]=++tot;id[tot]=u;fa[u]=f;for(auto v:node[u])dfs(v,u);R[u]=tot;} }T; /*克魯斯卡爾重構(gòu)樹*/ /*主席樹*/ struct Node {int l,r;int sum; }tree[N*40];int tot,root[N];void update(int num,int &k,int l,int r,int val) {tree[tot++]=tree[k];k=tot-1;tree[k].sum+=val;if(l==r)return;int mid=l+r>>1;if(num<=mid)update(num,tree[k].l,l,mid,val);elseupdate(num,tree[k].r,mid+1,r,val); }int query(int rt,int l,int r,int L,int R)//[l,r]:目標(biāo)區(qū)間,[L,R]:當(dāng)前區(qū)間 {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); }void init() {root[0]=0;tree[0].l=tree[0].r=tree[0].sum=0;tot=1; } /*主席樹*/ 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,m,q,st,opt,p,tot=0;scanf("%d%d%d%d%d",&n,&m,&q,&st,&opt);if(opt)scanf("%d",&p);T.init(n);for(int i=1;i<=n;i++)scanf("%d",c+i);for(int i=1,u,v,w;i<=m;i++){scanf("%d%d%d",&u,&v,&w);T.addedge(u,v,w);}T.solve();for(int i=1;i<=T.n;i++){root[i]=root[i-1];if(T.id[i]<=n){int x=T.id[i];if(pre[c[x]])update(pre[c[x]],root[i],1,T.n,-1);pre[c[x]]=i;update(pre[c[x]],root[i],1,T.n,1);}}int pos=st;while(pos!=0){tot++;cnt[tot]=query(root[T.R[pos]],T.L[pos],T.R[pos],1,T.n);t[tot]=T.val[pos];pos=T.fa[pos];}cnt[0]=1;t[0]=0;for(int i=1;i<=tot;i++)sum[i]=sum[i-1]+cnt[i-1]*(t[i]-t[i-1]-1)+cnt[i];LL last=0;while(q--){int l,r;scanf("%d%d",&l,&r);if(opt){l=(l^last)%p+1;r=(r^last)%p+1;if(l>r)swap(l,r);}l--;int ll=upper_bound(t+1,t+1+tot,l)-t-1;int rr=upper_bound(t+1,t+1+tot,r)-t-1;LL ans=(sum[rr]+(r-t[rr])*cnt[rr])-(sum[ll]+(l-t[ll])*cnt[ll]);printf("%lld\n",last=ans);}return 0; }

?

超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的牛客 - 牛半仙的妹子图(并查集+bitset/克鲁斯卡尔重构树+主席树)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 美日韩在线视频 | 日剧大尺度床戏做爰 | 亚洲一区二区三区人妻 | 狠狠鲁影院 | 双乳被四个男人吃奶h文 | 亚洲欧美日韩天堂 | 国产日韩欧美一区二区 | 91黄色小网站 | 黄色91视频 | 五月激情小说 | 天堂8av | 亚洲一区二区日韩欧美 | 国产a区 | 最新中文字幕免费 | 六月丁香激情网 | 成年人小视频 | 先锋影音制服丝袜 | 欧美com| 久久久婷| 91亚洲精品久久久久久久久久久久 | 国产ts人妖调教重口男 | 国产精品自拍偷拍视频 | 日剧大尺度床戏做爰 | 国产夫妻在线观看 | 国产福利免费 | 国产社区在线 | 97热久久| 成人做爰69片免费观看 | 深夜小视频在线观看 | 欧美人与禽猛交乱配视频 | 久久99国产精品 | 中文字幕精品三级久久久 | hs网站在线观看 | 午夜剧场黄色 | 日日射日日干 | 亚洲欧美在线观看视频 | 欧美亚洲色图视频 | 亚洲精品少妇 | 成a人v | 一区二区在线免费观看 | 人人人超碰 | 国产jk精品白丝av在线观看 | 亚洲日本中文字幕在线 | 丁香花完整视频在线观看 | 日韩亚洲欧美中文字幕 | 91在线观看. | 伊人久久久 | av午夜在线观看 | 精品人妻在线播放 | 久久精品无码专区免费 | 国产日韩一级 | 欧美男优| www.精品国产 | 黄色一级欧美 | 天天看片天天射 | 视频在线观看你懂的 | 毛片av在线 | 一级黄色片毛片 | 一级淫片免费 | 久久午夜影视 | 国产精品中文在线 | 欧美怡春院 | 伊伊成人网 | 玉米地疯狂的吸允她的奶视频 | 美女在线一区 | 中文字幕亚洲专区 | 精品一区日韩 | 肉色超薄丝袜脚交69xx | 亚洲成人福利 | 黄网免费在线观看 | 99精品视频播放 | 色综合网址 | 青青草视频免费观看 | 操三八男人的天堂 | 女性女同性aⅴ免费观女性恋 | 和黑帮大佬的365 | 精品自拍视频 | 日本黄色中文字幕 | 高清精品xnxxcom | 免费成人深夜夜行网站视频 | 夜夜躁日日躁狠狠久久av | 丝袜脚交免费网站xx | 亚洲AV综合色区无码国产播放 | 黄色一级片免费播放 | 久久天堂av综合合色蜜桃网 | 操丝袜美女视频 | 精品麻豆视频 | 长河落日电视连续剧免费观看01 | 一级免费大片 | 欧美人与性动交g欧美精器 国产在线视频91 | 麻豆tv在线观看 | 国产一级二级三级在线观看 | 性生交生活片1 | 国产网站在线免费观看 | 日本在线加勒比 | 久久成人福利视频 | 国产欧美日韩综合 | 永久免费的网站入口 | 老熟妇仑乱视频一区二区 |