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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

基站建设(三元环计数+根号分治 / bitset)

發布時間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基站建设(三元环计数+根号分治 / bitset) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基站建設

  • problem
  • solution
  • code

problem

給定 nnn 個地點,以及每個地點的可靠度 RiR_iRi?

mmm 條光纖架,每一條連接兩個不同的地點,且是雙向的。

測試基站由 444 個信號塔,有 222 個主信號塔和 222 個副信號塔。

要求主信號塔必須與其余三個塔相連,副信號塔必須與所有主信號塔相連。

每個地點都只能建一個信號塔,基站的可靠度為兩個主信號塔所在地點可靠度+1+1+1的乘積再加上兩個副信號塔所在地可靠度的乘積。即 (Ri+1)(Rj+1)+RaRb(R_i+1)(R_j+1)+R_aR_b(Ri?+1)(Rj?+1)+Ra?Rb?

求測試基站的最大可靠度。

n≤3e5,1s,512MBn\le 3e5,1s,512MBn3e5,1s,512MB

solution

observation:滿足條件的子圖其實上是有一條公共邊的兩個三元環。

求解公式并沒有什么特殊性質,所以很有可能是需要枚舉三元環的。

枚舉三元環既可以枚舉三個點,也可以枚舉三條邊,選擇不同帶來的時間效率也有所不同。

考慮根號分治。

對于度數 <m<\sqrt{m}<m? 的點,枚舉其兩條出邊再判斷兩條邊的入點之間是否有邊。

度數 >m>\sqrt{m}>m? 的點,總個數不超過 m\sqrt{m}m? 個。直接枚舉三個點。

時間復雜度均為 O(mm)O(m\sqrt{m})O(mm?)


上面的是正解,下面的是我在考場上自己想的做法。

最暴力的就是考慮一條邊,這條邊是連接主信號塔 u,vu,vu,v 之間的。

其實剩下的就是找 u,vu,vu,v 連接的點的交集之中可靠度最大的兩個點。

暴力枚舉邊就是 O(m2)O(m^2)O(m2) 的。但是一旦使用 bitset 就不一樣了。

直接 bitset 處理每個點直接相連的點的集合,將 u,vu,vu,v 的 bitset 直接取 &。

然后 bitset 也自帶快速找到為 111 的位置。

空間復雜度 O(n2)O(n^2)O(n2)。不卡!

時間復雜度是 O(nmω)O(\frac{nm}{\omega})O(ωnm?)

反正跑得挺快的。

code

#include <bits/stdc++.h> using namespace std; #define maxn 50005 #define maxm 200005 bitset < maxn > g[maxn]; pair < int, int > E[maxm]; int R[maxn]; int n, m;int main() {freopen( "station.in", "r", stdin );freopen( "station.out", "w", stdout );scanf( "%d %d", &n, &m );for( int i = 1;i <= n;i ++ ) scanf( "%d", &R[i] );for( int i = 1, u, v;i <= m;i ++ ) {scanf( "%d %d", &u, &v );E[i] = { u, v };g[u][v] = g[v][u] = 1;}int ans = 0;for( int i = 1;i <= m;i ++ ) {int u = E[i].first, v = E[i].second;bitset < maxn > son = g[u] & g[v];son[u] = son[v] = 0;int max1 = 0, max2 = 0;for( int k = son._Find_first();k != son.size();k = son._Find_next( k ) ) {if( R[k] > max1 ) max2 = max1, max1 = R[k];else if( R[k] > max2 ) max2 = R[k];}if( ! max1 or ! max2 ) continue;ans = max( ans, ( R[u] + 1 ) * ( R[v] + 1 ) + max1 * max2 );}printf( "%d\n", ans );return 0; }

總結

以上是生活随笔為你收集整理的基站建设(三元环计数+根号分治 / bitset)的全部內容,希望文章能夠幫你解決所遇到的問題。

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