a.給你一張n個點n-1條邊的圖,和k個關鍵點。求乙個點到所有關鍵點距離最大值的最小為多少。
乍一看像是對答案二分,但是考慮兩個相距最遠的關鍵點,假設他們的距離為d,那麼答案肯定為(d+1)/2
如果有一點到中心點的距離超過了(d+1)/2 ,那麼這個點會成為最遠關鍵點對中的乙個。矛盾。
所以題目就變成了如何求最遠的兩個關鍵點的距離。
考慮如何求樹的直徑,首先取乙個根節點通過bfs找到離他最遠的葉子節點p,然後將p當做根節點再跑一遍bfs
求出離這個點最遠的葉子節點q,那麼從p到q的這條路徑就是樹的直徑。
那麼兩個最遠的關鍵點的距離就相當求出將關鍵點當成葉子節點的一棵樹的直徑,我們取乙個點當根節點然後
bfs找到離他最遠的關鍵點p 以這個關鍵點p為根節點再跑一遍bfs求出離這個關鍵點最遠的關鍵點q,則p到q的路
徑就是我們要找關鍵點最遠距離d 然後 ans=(d+1)/2更新答案
#includeusing namespace std;
const int maxn=100005;
int n,k;
vectorg[maxn];
int vis[maxn],flag[maxn],dis[maxn];
int bfs(int x)
int y;
for(int i=1;i<=k;i++)
int s,t;
s=bfs(1);
t=bfs(s);
cout<<(dis[t]+1)/2首先考慮是3的倍數,要求乙個區間是三的倍數則將他的數字字首和%3 出現重複的時候,則區間l+1~r是3的倍數
則我們要求的區間s[r],s[r-1]均為0的時候,統計0~r-2中有多少滿足sx=0,1,2在s[r-1]更新答案,
模擬於30的倍數應該當s[r]=0時 在s[r]更新答案。
3000的倍數應該當s[r]=0,s[r-1]=0,s[r-2]=0時在s[r-2]更新答案。
特別 0 也是300的倍數所以每次遇到乙個0 ,ans++;
#include#define ll long long
using namespace std;
char s[100016];
int x[100016];
ll mp[6];
ll ans=0;
int main()
mp[x[i]]++;
}cout
}
2019牛客多校第四場 D triples I
對於二進位制每一位上的1進行考慮,2 0 3 1 2 1 3 2 2 2 3 1 2 3 3 2 那麼我們可以想到把a轉化為二進位制,然後他 3 1的位數有cnt1個,3 2的位數有cnt2個。我們可以想到每個數字最多由2個數字組成,下面給出證明。那麼 sum a 3,如果sum 0,那麼直接乙個數...
2019牛客多校第四場 A meeting
考場上寫了一大坨樹形dp,寫的時候就感覺我這不是跟求樹的最長鏈寫的一毛一樣 然後考後看題解,果然是k個ren所連成的子樹的最長鏈的一半 可以利用反證法證明,如果在長度為d的最長鏈的中間放乙個中心,如果有另外乙個點到這個點的長度 d 1 2,那麼這個點到對面的那個點的長度大於d,所以不存在這樣乙個點。...
2019牛客多校第四場A meeting 思維
乙個樹上有若干點上有人,找出乙個集合點,使得所有人都到達這個點的時間最短 無碰撞 就是找樹的直徑,找直徑的時候記得要找有人的點 include include includeusing namespace std define pb push back define f first define s...