給出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個人當中,最遠的那...