題目大意:動態最小生成樹,可以離線,每次修改後回答,點數20000,邊和修改都是50000。
顧昱洲是真的神:顧昱洲_**一類分治演算法
講的很妙,大致的幾個注意點在**裡面也有提到。
#include #include #include #include #include #include #define ll long longusing namespace std;
const int n = 50010;
const ll inf = 1e9+7;
struct updupd[n];
struct edge
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*res;
}inline int find(int x)
inline void clear(int tot)
}inline void contraction(int &tot,ll &tval,int cnt=0)
for(int i=1;i<=cnt;++i)
fa[que[i].x]=que[i].x,fa[que[i].y]=que[i].y;
for(int i=1;i<=cnt;++i)
cnt=0;
for(int i=1;i<=tot;++i)
tot=cnt;for(int i=1;i<=tot;++i)edge[i]=que[i];
//上面的操作是求出在樹中的、代價不為-inf的邊,並不忽略其他所有邊。
//即只清理掉了必在樹中的邊。
//若本來圖是(n,m,k),則變成了(k+1,m-k+1,k),主要還是在於點數的減少,變成與k=(r-l+1)線性相關。
//值得思考/學習的地方:並查集只清理關鍵點、最後乙個for中並沒有fa[f2]=f1操作的原因。
}inline void reduction(int &tot,int cnt=0)
fa[f1]=f2;que[++cnt]=edge[i],pos[edge[i].pos]=cnt;
} tot=cnt;for(int i=1;i<=tot;++i)edge[i]=que[i];
//上面的操作刪掉了必定不在生成樹中的邊。
//若本來圖是(n,m,k),則變成了(n,n+k-1,k)。
//又因為執行reduction操作前圖已經是(k+1,m-k+1,k)的了
//所以圖會變成(k,2k,k),減少了邊數,圖變得完全與k=(r-l+1)線性相關。
//所以每次做mst邊數和(r-l+1)(即k)線性相關,由主定理知複雜度是o(q*log_q*(log_q+α))。
}//contraction和reduction中都死死抓住了pos和edge之間的關係。
inline void solve(int l,int r,int dep,ll tval)
//pos和edge有很重要的關係。
//pos[i]指的是讀入順序的第i條邊在edge的下標。
//而edge.pos指的是這條邊是讀入的第幾條邊。
//即:pos[edge[i].pos]=i。
if(l==r)
ans[l]=tval;return;
} //遞迴邊界。這個時候的圖,也就一兩個點,一兩條邊了吧?
for(int i=l;i<=r;++i)edge[pos[upd[i].k]].val=-inf;
contraction(tot,tval);
for(int i=l;i<=r;++i)edge[pos[upd[i].k]].val=inf;
reduction(tot);enum[dep+1]=tot;
//**裡面的r-c-r的第乙個r是沒有必要的,只要c-r即可。
for(int i=1;i<=tot;++i)e[dep+1][i]=edge[i];
//這種記錄圖的方式很巧妙。
solve(l,mid,dep+1,tval);solve(mid+1,r,dep+1,tval);
//關鍵邊被修改成inf就這麼傳下去了……不過沒有任何關係。
}int main();
for(int i=1;i<=q;++i)upd[i]=(upd);
enum[0]=m;solve(1,q,0,0);
for(int i=1;i<=q;++i)printf("%lld\n",ans[i]);
return 0;
}
BZOJ1222 HNOI2001 產品加工
某加工廠有a b兩台機器,來加工的產品可以由其中任何一台機器完成,或者兩台機器共同完成。由於受到機器效能和產品特性的限制,不同的機器加工同一產品所需的時間會不同,若同時由兩台機器共同進行加工,所完成任務又會不同。某一天,加工廠接到n個產品加工的任務,每個任務的工作量不盡一樣。你的任務就是 已知每個任...
bzoj 1222 HNOI2001 產品加工
題意 有兩台機器,給出n個產品在1號機器 2號機器 兩台機器一起的加工時間,0表示不能以某種方式加工,問最快加工時間。題解 dp 很強。f i j 表示前i個產品,在2號機器上用了j的時間,1號機器用的時間。第一維滾一下。轉移看 include include include using names...
bzoj1225 HNOI2001 求正整數
description 對於任意輸入的正整數n,請程式設計求出具有n個不同因子的最小正整數m。例如 n 4,則m 6,因為6有4個不同整數因子1,2,3,6 而且是最小的有4個因子的整數。input n 1 n 50000 output msample input 4 sample output 6...