1343D - Constant Palindrome Sum 差分,D-逃亡的贝贝_二分最短路

110 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 21 天,点击查看活动详情

1343D - Constant Palindrome Sum 差分

可以看出对于一个x和a[i]来说,如果x属于[min(a[i],a[n-i+1])+1,max(a[i],a[n-i+1])+k]之间,那么第i组就只需要改一次,如果不属于就需要两次,特别的如果x=a[i]+a[n-i+1]不需要修改,这样就可以用一个差分数组来维护x的取值,最后选择一个最小的就可以

int t,n,k,a[200005],b[500005];
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        for(int i=1;i<=2*k;i++) b[i]=0;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n/2;i++)
        {
            int l=min(a[i],a[n-i+1])+1,r=max(a[i],a[n-i+1])+k;
            b[2]+=2;
            b[l]--;
            b[r+1]++;
            //因为a[i]+a[n-i+1]是在[l,r]之内的,刚才[l,r]内加了1,所以现在要减去1,才能保持不变
            b[a[i]+a[n-i+1]]-=1;
            b[a[i]+a[n-i+1]+1]+=1;
        }
        int ans=1e18;
        for(int i=2;i<=2*k;i++) b[i]+=b[i-1],ans=min(ans,b[i]);
        cout<<ans<<endl;
    }
    return 0;
}
//

D-逃亡的贝贝_二分最短路

题意: 现在地球上有nnn个城市,这n个城市之间有m条双向道路,每条道路都有个风险值w(w>0),风险值越大表示这条道路上的外星人越多,也就是这条道路越危险。为了抵御外星人,人类在T号城市建立了安全区,于是贝贝现在所需要做的最重要的事情,就是前往安全区。为了帮助贝贝,Z博士研发了N药水,一瓶药水能大大强化使用者的战斗力,每瓶N药水可以将道路的风险值w降低为114w514\lceil\frac{114w}{514}\rceil其中数学符号x⌈x⌉,表示最小的不小于x的整数),一条道路最多使用一次N药水。现在贝贝身处S号城市,身上有k瓶N药水,想要转移到T号城市(安全区),他想知道他一路上所要路过的最大风险值的道路的最小值是多少(若不需要经过任何道路即可到达则为0)。若贝贝无法到达安全区,则输出

I really need TS1's time machine again!

二分答案,如果该条边的权值小于mid就改为0,用药水之后小于mid就改为1,用药水之后还是大于mid就改为inf,最后看看dist[T]是否<=k就可以了

牛客练习赛104【出题人题解】 - 知乎 (zhihu.com)

int head[400005],cnt;
struct Edge
{
    int next,to,dis;
}e[400005];
void addedge(int from,int to,int dis)
{
    e[++cnt].to=to;
    e[cnt].dis=dis;
    e[cnt].next=head[from];
    head[from]=cnt;
}
int n,m,S,T,K,vis[200005],dist[200005];
struct node
{
    int id,dis;
    bool operator<(const node &a)const
    {
        return a.dis<dis;
    }
};
struct Input
{
    int u,v,dis;
}in[200005];
void dij(int x)
{
    priority_queue<node>q;
    q.push(node{S,0});
    for(int i=1;i<=n;i++) dist[i]=inf;
    for(int i=1;i<=n;i++) vis[i]=0;
    dist[S]=0;
    while(!q.empty())
    {
        node a=q.top();q.pop();
        int now=a.id;
        if(vis[now]) continue;
        vis[now]=1;
        for(int i=head[now];i;i=e[i].next)
        {
            int j=e[i].to;
            int t=e[i].dis;
            if(t<=x) t=0;
            else if((t*114+513)/514<=x) t=1;
            else t=inf;
            if(dist[now]+t<dist[j])
            {
                dist[j]=dist[now]+t;
                q.push(node{j,dist[j]});
            }
        }
    }
}
bool check(int x)
{
    dij(x);
    //cout<<x<<" "<<dist[T]<<endl;
    return dist[T]<=K;
}
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    cin>>n>>m>>S>>T>>K;
     for(int i=1;i<=m;i++)
    {
        int u,v,dis;
        cin>>u>>v>>dis;
        addedge(u,v,dis);
        addedge(v,u,dis);
    }
    int ans=inf,l=0,r=1e9;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    if(ans==inf) cout<<"I really need TS1's time machine again!"<<endl;
    else cout<<ans<<endl;
    //cout<<dist[T]<<endl;
    return 0;
}
//