先考慮乙個子問題:僅有乙個詢問且無修改
對每一種顏色的貢獻分類討論,結論:最遠的點一定這些點集中(任意一組)最遠點對中的兩個點(選擇較遠的乙個)
證明:設$dis(x,y)$為$x$到$y$的距離,$deep_$表示以$k$為根時$x$的深度
假設這個點集中最遠點為$(x,y)$,而最深的點為$z$,且$deep_$嚴格大於$deep_$和$deep_$
乙個顯然的性質:$deep_\le deep_,deep_$
考慮$w=lca(x,y,z)$,若$z=w$與$deep_>deep_,deep_$矛盾,因此假設$z$在$w$的某個兒子$w_$中
當若$x$和$y$都在$w_$的子樹中顯然$lca(x,y,z)$可以為$w_$,因此必然存在乙個點在其子樹外,不妨設為是$x$,則$lca(x,z)=w$,必然有$deep_\le deep_$
考慮此時$dis(x,z)$與$dis(x,y)$,通過lca的形式展開,由於$deep_>deep_$且$deep_\le deep_$,因此$dis(x,z)>dis(x,y)$,與$(x,y)$為最遠點對矛盾
通過合併的方式(即不斷插入乙個點,三個點兩兩求$dis$)求出每乙個點集的最遠點對$(x,y)$,這一部分可以做到$o(n\log_n)$
進一步的,不妨假設$deep_\ge deep_$(此時的$deep$為以1為根),通過倍增找到$z$滿足$z$在$x$到$lca(x,y)$的路徑上且$dis(x,z)dis(k,x)$當且僅當$k$在$z$子樹中
特別的,當$x=y$時令$z=x$,這是為了方便處理,證明比較顯然,這裡就省略了
接下來,考慮對答案的貢獻,分為兩部分:
1.$z$的子樹中,點$k$的答案加上$deep_+deep_-2depp_$,首尾兩個式子都為常數,線段樹+dfs序即可,$deep_$通過打「區間加點深度」的標記,再維護區間內所有點深度和即可處理
2.$z$的子樹外,考慮$deep_+deep_-2deep_$,前兩個式子與上面處理方式相同,考慮第三個式子——
再建一棵線段樹,將$fa_$到根的路徑打上「減2倍其到父親的邊權」,那麼乙個點所需要減的就是其到根路徑上所有點的和,同時對$z$的子樹內部沒有影響,因此應對$z$的子樹區間加$fa_$的深度
這個考慮在詢問時處理,假設詢問$k$的子樹,對於$k$到根路徑上的所有點都會被減小$k$子樹大小次,之後對於$k$子樹內部的點會被減小子樹大小次
分別維護這個值以及這個值乘對應子樹大小的兩顆線段樹就可以處理了,另外鏈修改需要樹鏈剖分,總複雜度為$o(n\log^n)$
(注意,這樣兩顆線段樹是獨立的,也就是對兩邊的貢獻用不同的方式計算)
對於修改,可以看作在某種顏色中插入/刪除乙個點,對於插入同樣直徑合併(之後重新修改),刪除可以用線段樹來做,同樣利用直徑合併的性質就可以做了(注意修改完直徑後都要重新計算貢獻)
1 #include2view codeusing
namespace
std;
3#define n 200005
4#define ll long long
5#define l (k<<1)
6#define r (l+1)
7#define mid (l+r>>1)
8#define pii pair9
#define fi first
10#define se second
11struct
jiedge[n];
14int e,n,m,t,x,p,a[n],head[n],d1[n],d2[n],sz[n],son[n],dfn[n],inv_dfn[n],top[n],fa[n][21
];15
int v,pos[n],rt[n],ls[n*40],rs[n*40
];16 vectorv[n];
17 pii fd[n*40
];18 ll val[4][n<<2],tag[4][n<<2],f[4][n<<2
];19
void add(int x,int y,int
z)25
void dfs1(int k,int s1,int
s2)36}37
void dfs2(int k,int
t)46}47
int lca(int x,int
y)57
return fa[x][0
];58}59
int dis(int x,int
y)63
pii merge(pii x,pii y)79}
80return
ans;81}
82void update(int &k,int l,int r,int x,int
y)88
if (x<=mid)update(ls[k],l,mid,x,y);
89else update(rs[k],mid+1
,r,x,y);
90 fd[k]=merge(fd[ls[k]],fd[rs[k]]);91}
92void up(int
k)95
void upd(int p,int k,int
x)99
void down(int
k)106
}107
void build(int k,int l,int
r)117
build(l,l,mid);
118 build(r,mid+1
,r);
119for(int i=0;i<4;i++)val[i][k]=val[i][l]+val[i][r];
120}
121void update(int p,int k,int l,int r,int x,int y,int
z)127
down(k);
128update(p,l,l,mid,x,y,z);
129 update(p,r,mid+1
,r,x,y,z);
130up(k);
131}
132 ll query(int p,int k,int l,int r,int x,int
y)138
void calc(int k,int
p)150 update(0,1,1,n,dfn[z],dfn[z]+sz[z]-1,p*(d2[y]-2*d2[lca(x,y)]));
151 update(0,1,1,n,1,dfn[z]-1,p*d2[x]);
152 update(0,1,1,n,dfn[z]+sz[z],n,p*d2[x]);
153 update(1,1,1,n,1
,n,p);
154 update(0,1,1,n,dfn[z],dfn[z]+sz[z]-1,2*p*d2[fa[z][0
]]);
155 z=fa[z][0
];156
while (z>1
)161
}162 ll query(int
k)172
return
ans;
173}
174int
main()
181 memset(head,-1,sizeof
(head));
182 fa[1][0]=1
;183
for(int i=2;i<=n;i++)scanf("
%d",&fa[i][0
]);184
for(int i=2;i<=n;i++)
188 dfs1(1,0,0
);189 x=0
;190 dfs2(1,1
);191 build(1,1
,n);
192for(int i=1;i<=n;i++)update(rt[a[i]],1,n+m,pos[i],i);
193for(int i=1;i<=t;i++)calc(i,1
);194
for(int i=1;i<=m;i++)
208}
209 }
整合任務排程服務
jdk中任務排程核心是timer類的schedule方法,傳遞乙個繼承timertask實現了run方法的類。在spring的xml檔案中配置 b 使用quartz排程任務 b quartz中的幾個概念 job 定義乙個任務,job只管執行,不管什麼時間執行,不管執行多少次 trigger 定義乙個...
處理機排程 先來先服務排程(FCFS)
在多道程式系統中,排程的實質是一種資源分配。處理機排程是對處理機資源進行分配。處理排程演算法是指根據處理機分配策略所規定的的處理機分配演算法。此系列都是實現的非搶占的排程演算法。先來先服務排程 按照程序的先後進入次序進行排程 輸入 作業的數目,作業的到達時間與服務時間.輸出 作業的呼叫序列與其周轉時...
服務框架訊息排程效能測試
測試環境 cpu intel core i5 4590 cpu 3.30ghz 4核,64位 記憶體 8g 交換機速率 10 100mbps 伺服器網絡卡速率 100mbps 測試資料 一 服務同節點訊息處理個數 每個服務跑滿1個cpu 100 1 32位元組以內 1000萬 秒 2 64位元組 9...