中位数

题意:给一个序列,m次操作,每次操作给两个数,p,x,把a[p]改成x,问每次操作后中位数是多少

思路:修改用树状数组,将a[p]--,然后将x++;查询二分查询树状数组,查询值为1到mid的数字有多少个,如果是一半,则mid为中位数

代码:

#include<bits/stdc++.h>
using namespace  std;
const int N=1e6+5;
int n,m;
int tree[N],a[N];
int lowbit(int x){
    return  x&-x;
}
void add(int x,int k){
    for (int i = x; i <=N ; i+= lowbit(i)) {
        tree[i]+=k;
    }
}
int check(int x){
    int res=0;
    for (int i = x; i >0 ; i-= lowbit(i)) {
        res+=tree[i];
    }
    return res;
}
int main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    cin>>n>>m;
    for (int i = 1; i <=n ; ++i) {
        cin>>a[i];
        add(a[i],1);
    }
    int t=(n+1)/2;
    while (m--){
        int x,y;
        cin>>x>>y;
        add(a[x],-1),add(y,1);
        a[x]=y;
        int l=0,r=N;
        int ans=-1;
        while(l<=r){
            int mid=l+r>>1;
            if(check(mid)>=t)r=mid-1,ans=mid;
            else l=mid+1;
        }
        cout<<ans<<endl;
    }

}

松鼠回家

题意:给一个图,松鼠由起点st到终点ed,每个点都会扣除松果,每条边都有一个长度,问从起点到终点的路径的长度和小于H的情况下,在路上扣除的最大的松鼠的数量最小是多少。

思路:二分,松鼠数量,djstl跑一遍最短路,最短距离是否小于H

代码:

#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
#define int long long
int n,m,st,ed,h;
vector<PII>q[10004];
int d[10004];
signed main(){
    cin>>n>>m>>st>>ed>>h;
    for(int i=1;i<=n;i++)cin>>d[i];
    while(m--){
        int x,y,z;
        cin>>x>>y>>z;
        q[x].push_back({y,z});
        q[y].push_back({x,z});
    }
    auto check=[&](int mid){
        vector<int>vis(n+1,0),dis(n+1);
        for(int i=0;i<=n;i++)dis[i]=1e9;
        queue<int>g;
        g.push(st);
        dis[st]=0;
        vis[st]=1;
        while(g.size()){
            auto t=g.front();
            g.pop();
            vis[t]=0;
            for(auto u:q[t]){
                int dian=u.first;
                int b=u.second;
                if(d[dian]>mid)continue;
                if(dis[dian]>dis[t]+b){
                    dis[dian]=dis[t]+b;
                    if(vis[dian]==0){
                        vis[dian]=1;
                        g.push(dian);
                    }
                }

            }
        }
        if(h>=dis[ed])return true;
        else return false;
    };
    int l=0,r=1e7;
    int ans=-1;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid))r=mid-1,ans=mid;
        else l=mid+1;    
    }
    cout<<ans<<endl;

}
posted on 2023-07-17 19:52  IR101  阅读(25)  评论(0编辑  收藏  举报  来源