知識點:graph
分塊
[hdu 4858專案管理]有n
個頂點m條邊的無向圖。有
q 次操作:
- 操作一:將所有與
u相連的頂點權值加
v ;
- 操作二:查詢頂點
u的權值。
資料範圍:(1
<=
n<=
100000,1
<=
m<=n+
10,0<=
v<=
100)
分塊的一道比較好的題目吶。首先,觀察題目,給定的是乙個明顯的稀疏圖。邊數為
m ,那麼所有頂點度數之和是2∗
m。 那麼,顯然:不會超過有2∗
m−−−
−−√ 個頂點的度數大於2∗
m−−−
−−√ 。
那麼我們可以以2∗
m−−−
−−√ 為分界值進行分塊了。
- 對於所有度數小於2∗
m−−−
−−√ 的頂點,我們直接將權值累加到與
u 相連的頂點中去;
- 對於所有度數大於等於2∗
m−−−
−−√的頂點,我們則將
v 先累加到
u的標記上面【這個需要再建乙個圖】;
那麼查詢的時候,就是兩部分貢獻之和。這樣,就可以將複雜度控制在o(
q∗2∗
m−−−
−−√)
#include
using
namespace
std;
typedef __int64 ll;
typedef
long
double lb;
typedef pair pii;
typedef pairpll;
const
int inf = 0x3f3f3f3f;
const ll infl = 0x3f3f3f3f3f3f3f3fll;
const lb eps = 1e-8;
const
int maxn = 100000 + 15;
struct edge edge[maxn << 1];
int head[maxn], tot;
int n, m, q, du[maxn];
ll tag[maxn], ans[maxn];
vector
g[maxn];
inline
void add_edge(int& u, int& v) ;
head[u] = tot ++;
}void init()
int main()
base = sqrt(2 * m);
for(int x = 1; x <= n; ++x)
scanf("%d", &q);
while(q --)
for(int i = head[u]; ~i; i = edge[i].next) ans[edge[i].v] += v;
} else }}
return
0;}
hdu 4858 專案管理 分塊
我們建造了乙個大專案!這個專案有n個節點,用很多邊連線起來,並且這個專案是連通的!兩個節點間可能有多條邊,不過一條邊的兩端必然是不同的節點。每個節點都有乙個能量值。現在我們要編寫乙個專案管理軟體,這個軟體呢有兩個操作 1.給某個專案的能量值加上乙個特定值。2.詢問跟乙個專案相鄰的專案的能量值之和。如...
HDU4858 專案管理(分塊)
這道題展示了分塊的強大,學到一手,雖然因為資料太過友好暴力也能過 這道題邊數多,直接遍歷複雜度很高,大佬們想到了一種分攤複雜度的方法 對於入度大於指定值例如 sqrt 這也是分塊常用指定值的點,我們定義為重點 否則為輕點,重點只和重點連,輕點和輕點連。這基於的原理是,重點的個數不超過sqrt個,並且...
HDU 4858 專案管理
我們建造了乙個大專案!這個專案有n個節點,用很多邊連線起來,並且這個專案是連通的!兩個節點間可能有多條邊,不過一條邊的兩端必然是不同的節點。每個節點都有乙個能量值。現在我們要編寫乙個專案管理軟體,這個軟體呢有兩個操作 1.給某個專案的能量值加上乙個特定值。2.詢問跟乙個專案相鄰的專案的能量值之和。如...