D - Hidden Weights
题目:
思路:
代码:
#include <bits/stdc++.h>
#define fi first;
#define se second;
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=2e5+10;
const LL lnf=0x3f3f3f3f3f3f3f3f;
int n, m;
int h[N], e[N<<1] ,ne[N<<1], w[N<<1], idx;
LL res[N];
void add(int a,int b, int c)
{
e[idx]=b, ne[idx]=h[a], w[idx]=c, h[a]=idx++;
}
void dfs(int u)
{
for(int i=h[u]; ~i; i=ne[i]){
int v=e[i];
if(res[v]!=lnf) continue;
res[v]=res[u]+w[i];
dfs(v);
}
}
int main()
{
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--){
int u, v, c;
cin>>u>>v>>c;
add(u, v, c), add(v, u, -c);
}
memset(res, 0x3f, sizeof res);
for(int i=1; i<=n; i++){
if(res[i]==lnf){
res[i]=0;
dfs(i);
}
}
for(int i=1; i<=n; i++){
cout<<res[i]<<" ";
}
cout<<"\n";
return 0;
}
E - How to Win the Election
题目:
思路:
二分这个人需要的票数x,现在这个人的票数now=a[i]+x,,二分找的小于等于这个票数的人的位置,如果不在后m个人中,则不能当选; 如果在,我们需要统计从这人开始到第m个人,选票大于now需要的票数,剩余票是否能满足,需要注意,如果,这人原本就在后m个,我们需要分讨,减去这个原本的票数。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
LL n,m,k;
cin>>n>>m>>k;
vector<LL> a(n+1),b(n+1),pre(n+1);
for(int i=1; i<=n; i++){
cin>>a[i];
b[i]=a[i];
}
if(n==1){
cout<<0<<'\n';
return 0;
}
if(n==m){
for(int i=1; i<=n; i++){
cout<<0<<' ';
}
cout<<'\n';
return 0;
}
sort(b.begin(), b.end());
for(int i=1; i<=n; i++){
pre[i]=pre[i-1]+b[i];
}
LL sum=pre[n];
for(int i=1; i<=n; i++){
auto check = [&](LL x)-> bool{
LL now=a[i]+x, rest=k-sum-x, pos=upper_bound(b.begin(),b.end(), now)-b.begin()-1;
if(a[i]<b[n-m+1]){
if(pos<n-m+1) return false;
return (pos-(n-m))*(now+1)- (pre[pos]-pre[n-m])> rest;
} else {
return (pos-n+m)*(now+1)-(pre[pos]-pre[max(0LL ,n-m-1)]-a[i]) > rest;
}
};
LL l=0, r=k-sum, res=-1;
while(l<=r){
LL mid=l+r>>1;
if(check(mid)) r=mid-1, res=mid;
else l=mid+1;
}
cout<<res<<' ';
}
cout<<'\n';
return 0;
}