2019牛客暑假多校訓練營(第四場)

2021-09-25 21:29:35 字數 3327 閱讀 3012

給出n個點,和相連的邊,k個人,讓k個人在最短時間內同一地點相遇。

一句話題解:考慮距離最遠的兩個關鍵點,設它們的距離為d,d/2上取整即為答案。

• 必要性:這兩個人要碰面,必然要走至少d/2步。

• 充分性:我們取兩人路徑中和一頭距離為d/2上取整的乙個點,讓所有人在這相聚。如

果有乙個人在d/2時間內到不了,那麼它和路徑兩頭中與它遠的那一頭的距離大於d,與

最遠的假設矛盾。

• 找到這樣最遠的一對點類似找樹的直徑。可以直接dp,也可以採用兩遍bfs:從任意乙個關

鍵點開始,找到離它最遠的關鍵點x,再從x開始bfs,找到的新的最遠點和x形成的就是直徑。

兩次bfs找到直徑,向上取整除以二

#includeusing namespace std;

const int maxn=1e5+5;

int n,k,a,b;

vectorv[maxn];

queueq;

bool vis[maxn];

int d[maxn],mx,l,pos[maxn];

void bfs(int s)

q.push(y);

vis[y]=1;}}

}int main()

。找到a數列的每個值是最小值的區間 l,r,用單調棧。

維護b數列字首和的最大值和最小值,sum(b[l..r])=s[r]-s[l-1]。

分類討論a[i]為正還是負,查詢  i..r-1最大的s  和  l..i-1最小的s,相減即可

#includeusing namespace std;

typedef long long ll;

const ll maxn=3e6+5;

const ll inf=1e18;

ll n,a[maxn],b[maxn],s[maxn],l[maxn],r[maxn];

stacksl,sr;

struct tree

t[maxn*4+5];

ll x,y;

void build(ll l,ll r,ll k)

ll mid=(l+r)/2;

build(l,mid,k*2);

build(mid+1,r,k*2+1);

t[k].mi=min(t[k*2].mi,t[k*2+1].mi);

t[k].mx=max(t[k*2].mx,t[k*2+1].mx);

}ll ask1(ll k)

ll mii=inf;

ll mid=(t[k].l+t[k].r)/2;

if(x<=mid) mii=min(mii,ask1(k*2));

if(y>mid) mii=min(mii,ask1(k*2+1));

return mii;

}ll ask2(ll k)

ll mxx=-inf;

ll mid=(t[k].l+t[k].r)/2;

if(x<=mid) mxx=max(mxx,ask2(k*2));

if(y>mid) mxx=max(mxx,ask2(k*2+1));

return mxx;

}}t;int main()

t.build(1,n,1);

for(ll i=1;i<=n;i++)

for(ll i=n;i>0;i--)

ll mx=-inf,vl,vr;

for(ll i=1;i<=n;i++)

else

}printf("%lld\n",mx);

return 0;

}

給出乙個數,用最少數量的3的倍數配湊出該數,運算為或。

• 分類討論。

• 乙個二進位制位mod 3只可能是1或者2。

• 如果a是3的倍數,那麼我們直接取即可。

• 否則如果a的二進位制位只有一位或兩位,我們根本取不出0以外的三的倍數,所以無解。

• 接下來考慮a至少有三位的情況。

• 若a mod 3=1:

• 如果a中的二進位制位有至少兩個mod 3=1的,設它們為p和q,我們取即可。

• 如果a中的二進位制位有恰好乙個mod 3=1的,那麼設mod 3=1的這個位為p,mod 3=2

的某個位為q,我們取即可。

• 如果a中的二進位制位沒有mod 3=1的,那麼假設有三個mod 3=2的位p,q,r,我們取即可。

• 若a mod 3=2只需把上面的討論中1與2互換即可,是完全對稱的。

把3的倍數的數找到,其他的羅列出來,看區別,就可以想到消掉某一位1,2,4,8等等。

#includeusing namespace std;

typedef long long ll;

vectorv[3];

int main()

ll m=n,vv=1;

//記錄哪個位置有1

while(m)

vv*=2;

m/=2;

}if(n%3==1)

else if(v[1].size()==1&&v[2].size())

else if(v[1].size()==0&&v[2].size()>=3)

}else

else if(v[2].size()==1&&v[1].size())

else if(v[2].size()==0&&v[1].size()>=3)}}

return 0;

}

給出n個點,m條邊,s起點,t終點,k可忽略掉的邊權。求最小花費。分層圖!?也不用,直接優先佇列加bfs

#includeusing namespace std;

typedef long long ll;

ll n,m,s,t,k;

ll a,b,c,ans;

struct edge

;struct node

); while(!q.empty())

for(ll i=0;i給出一串字串,求子串是300的倍數的數量,包括0.

300的倍數滿足既是3的倍數,也是100的倍數。

用字首和處理s[r]-s[l-1]=0,且s[r]、s[r+1]為0,則計算。

#includeusing namespace std;

typedef long long ll;

char s[100005];

ll sum=0,cnt[5];

int main()

cnt[sum]++;

}printf("%lld\n",ans);

return 0;

}

2019牛客暑假多校訓練營(第五場)

矩陣快速冪,a n,n特別大,想到求某數sum sum 10 s i 0 可以把n一位一位拆開,ans ans 10 st s i 0 指數相加所以分開相乘 十進位制優化類似快速冪!includeusing namespace std typedef long long ll const ll ma...

2019牛客暑期多校訓練營(第四場

a meeting 答案為最遠關鍵點的距離的一半向上取整,也就是關鍵點的樹的直徑的一半向上取整。先考慮兩個點,他倆是最遠距離,那麼最短時間就是 d 2 在此基礎上再加乙個點 前提是加上這個點,後不影響初始條件,即初始的兩個點之間的距離最遠 那麼不會影響答案,因為他與另外兩個點的相會的時間必然小於 d...

2019牛客暑期多校訓練營(第四場)A

題意 給定n個頂點,n 1條邊權為1的邊,將各個頂點連成乙個最小生成樹,再給定乙個k,表示有多少個人,每個人都在特點的乙個頂點上,現在這些人要相會,求使得這些人能夠相聚在一起的最短時間。看了標程,答案就是k個人當中那2個距離最遠的人的距離d,答案就是d 2向上取整。證明 必要性 k個人當中,最遠的那...