給了些關鍵點 在一棵樹上 選取乙個點讓他們相聚 時間最短
其實就是求樹直徑 不過這次dfs完 我們找最遠點的時候只看標記點 第二次dfs完也一樣
#include
using namespace std;
const
int maxn =
1e5+5;
int n, m, cnt;
int head[maxn]
, d[maxn]
;int to[maxn <<1]
, nxt[maxn <<1]
;bool v[maxn]
;void
ade(
int a,
int b)
void
dfs(
int x,
int pre)
}int
main()
for(
int i =
1, a; i <= m; i ++
) cin >> a, v[a]=1
; d[1]
=0,dfs(1
,-1)
;int rt =-1
, tmp =-1
, ans =-1
;for
(int i =
1; i <= n; i++)if
(v[i]
&& d[i]
> tmp)
d[rt]=0
,dfs
(rt,-1
);for(
int i =
1; i <= n; i ++)if
(v[i]
&& d[i]
> ans)
ans = d[i]
; cout <<
(ans +1)
/2<< endl;
return0;
}
on 是什麼做法啊orz
給你乙個長度n的序列 選取乙個數字 和b包含它區間(而且它必須是這個區間的最小值) 使a[i]*(這一區間的和) 最大
首先單調棧 處理每個a[ i ] 管理區間(沒有比它小的最大連續區間)
然後 對 a[ i ] 分2種情況 正負來考慮
大於 0 的情況 顯然是 它 管理的區間和 *a[ i ] 因為a[i]>0 同時它肯定是這區間最低點 該區間越長和越大
小於 0 的情況 不妨我們維護乙個 字首和 既然它是負數 我們 當前i 到r[ i ]字首和最好越小越好 而l[ i ] 到 i得和越大越好
#include
#define fastio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define int long long
using namespace std;
typedef
long
long ll;
const
long
long inf =
0x3f3f3f3f3f3f3f3f
;const
int maxn =
3e6+5;
int n;
ll a[maxn]
,sum[maxn]
, b[maxn]
;int l[maxn]
,r[maxn]
;struct node tr[maxn<<2]
;void
pushup
(int rt)
void
build
(int l,
int r,
int rt)
;return;}
int mid=
(l+r)
>>1;
build
(l,mid,rt<<1)
;build
(mid+
1,r,rt<<1|
1);pushup
(rt);}
ll maxquery
(int l,
int r,
int l,
int r,
int rt)
int mid=
(l+r)
>>1;
ll res=
-inf;
if(l<=mid) res=
max(res,
maxquery
(l,r,l,mid,rt<<1)
);if(r>mid) res=
max(res,
maxquery
(l,r,mid+
1,r,rt<<1|
1));
return res;}
ll minquery
(int l,
int r,
int l,
int r,
int rt)
int mid=
(l+r)
>>1;
ll res=inf;
if(l<=mid) res=
min(res,
minquery
(l,r,l,mid,rt<<1)
);if(r>mid) res=
min(res,
minquery
(l,r,mid+
1,r,rt<<1|
1));
return res;
}void
sollr()
while
(!s.
empty()
) s.
pop();
for(
int i=n; i>=
1; i--)}
signed
main()
else
}printf
("%lld\n"
,ans)
;return0;
}
d triples i
把這個資料拆成 21212121 的樣子
n % 3 == 0 直接輸出
n % 3 == 1 我們考慮 如果 補 1 夠 2個 我們直接 n - b[1] n - b[0];
如果 二進位制中貢獻 1 的只有乙個 我們選擇 b[0] + c[0] 和 n - b[0];
else 我們選擇 用 2位置補成3倍數 c[0] + c[1] + c[2] 和 n - c[0] - c[1];
n % 3 == 2 與上面相反
#include
typedef
long
long ll;
using namespace std;
vector b, c;
intmain()
else
x <<=1;
}if(n %3==
1)else}}
return0;
}
j free
老題 分層圖dj水過
#include
#define a first
#define b second
using namespace std;
const
int maxn =
1e3+10;
int head[maxn]
, cnt;
int nxt[maxn <<1]
, d[maxn <<1]
, to[maxn <<1]
;int n, m, s, t, k;
void
ade(
int a,
int b,
int c)
typedef pair<
int,
int> p;
typedef pair<
int, pair<
int,
int>> pp;
priority_queue
,greater
> que;
int dis[maxn]
[maxn]
;bool vis[maxn]
[maxn]
;voiddj(
)if(u.b < k && dis[v]
[u.b +1]
> dis[u.a]
[u.b])}
}}signed
main()
dj();
cout << dis[t]
[k]<< endl;
return0;
}
k number
比如說 123400
我們先統計單個0
ans += 2;
然後字首和 123400
#… .% 3後 100111
我們可以整除300 的地方 只有 3 和 100 的倍數
也就是 2個0已經出現 0 對應的1 之前 第乙個 1 之後的資料 就可以整除 300 記錄餘數 每次遇到便加上
#include
using namespace std;
const
int maxn =
1e5+10;
int sum[maxn]
, cnt[5]
;char str[maxn]
;int
main()
for(
int i =
1; i <= len; i ++
) cout << ans << endl;
return0;
}
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 K
a.給你一張n個點n 1條邊的圖,和k個關鍵點。求乙個點到所有關鍵點距離最大值的最小為多少。乍一看像是對答案二分,但是考慮兩個相距最遠的關鍵點,假設他們的距離為d,那麼答案肯定為 d 1 2 如果有一點到中心點的距離超過了 d 1 2 那麼這個點會成為最遠關鍵點對中的乙個。矛盾。所以題目就變成了如何...