zoukankan      html  css  js  c++  java
  • 无题十一

    题解:

    第一题:其实上次做过一次,但是这次搞了半天都没搞出来;

    这是典型的后悔贪心,我们开两个小根堆,第一个堆存现在有那些可以卖出去,第二个后悔堆存卖出的;

    如果取可以第一个堆的更优,我们加上利润,把这个卖出的物品丢掉,然后把物品卖出放进后悔堆,表示我当前这个这个物品或许应该买进,对后面的贡献更大;

    否则还是加上利润,然后我们把第二个堆的这个物品放回第一个堆,因为这个物品不是我们真正卖掉的,他只是中间的一个媒介(实际卖掉的是这个物品进第二个堆是堆1pop掉的物品),所以他是可以继续对后面产生贡献的;

    #include<bits/stdc++.h>
    using namespace std;
    priority_queue <int, vector<int>, greater<int> > q1, q2;
    int a[100005], inf = 2e9;
    int main(){
        freopen("trade.in","r",stdin);
        freopen("trade.out","w",stdout);
        int n;
        long long ans = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            if(q1.empty() && q2.empty())q1.push(a[i]);
            else {
                int b1 = inf, b2 = inf;
                if(!q1.empty()) b1 = q1.top();
                if(!q2.empty()) b2 = q2.top();
                if(b1 >= a[i] && b2 >= a[i]) q1.push(a[i]);
                else if(b1 <= b2) {
                    ans += 1LL*(a[i] - b1);
                    q1.pop();
                    q2.push(a[i]);
                }
                else {
                    ans += 1LL*(a[i] - b2);
                    q1.push(b2);
                    q2.pop();
                    q2.push(a[i]);
                }
            }
        
        }
        printf("%lld
    ", ans);
    }
    View Code

    第二题:打表+莫队

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define RG register
    const int M2 = 1e5 + 5;
    ll ret[M2], fac[M2], vfac[M2];
    const ll mod = 1e9 + 7;
    inline ll moc(ll a){return a >= mod ? a - mod : a;}
    ll ksm(ll a, int b){
        ll ret=1;
        for(;b;b>>=1,a=a*a%mod)
            if(b&1)ret=ret*a%mod;
        return ret;
    }
    int N = 1e5, inv2, siz = 300, block[M2];
    struct Query{int n, m, id;}q[M2];
    bool cmp(Query a, Query b){return block[a.m] == block[b.m] ? a.n < b.n : a.m < b.m;}
    
    void init(){
        fac[0] = vfac[0] = 1;
        for(ll i = 1; i <= N; i++) {
            fac[i] = fac[i - 1] * i % mod;
            block[i] = i/siz + 1;
        }
        inv2 = ksm(2, mod - 2);
        vfac[N] = ksm(fac[N], mod - 2);
        for(ll i = N - 1; i; i--) vfac[i] = vfac[i + 1] * (i + 1) % mod;
    }
    ll C(int n, int m){
        if(m > n) return 0;
        return fac[n] * vfac[m] % mod * vfac[n-m] % mod; 
    }
    
    int main(){
        int id, Q;
        freopen("sum.in","r",stdin);
        freopen("sum.out","w",stdout);
        scanf("%d", &id);
        init();
        scanf("%d", &Q);
        for(int i = 1; i <= Q; i++) scanf("%d%d", &q[i].n, &q[i].m), q[i].id = i;
        sort(q + 1, q + 1 + Q, cmp);
        int n = 0, m = 0;
        ll ans = 1;
        for(int i =1; i <= Q; i++){
            
            while(q[i].m < m){
                ans = (ans - C(n, m) + mod) % mod;
                m--;
            }
            while(q[i].n > n){
                ans = (2LL*ans - C(n, m) + mod) % mod;
                n++;
            }
            while(q[i].m > m){
                m++;
                ans = (ans + C(n, m)) % mod;
            }
            while(q[i].n < n){
                n--;
                ans = (ans + C(n, m)) * inv2 % mod;
            }
            //if(i!=1)printf("%d %d %lld
    ", n,m,ans);
            ret[q[i].id] = ans;
        }
        for(int i = 1; i <= Q; i++)printf("%lld
    ", ret[i]);
        return 0;
    }
    View Code

    第三题:其实算一个模拟吧,二分+并查集合并

    #include<bits/stdc++.h>
    using namespace std;
    #define For(a, b, c) for(int a=b;a<=c;a++)
    const int M = 1e5 + 10;
    int sum[M], cf[M], fa[M], mix, ans[M], scc[M]; 
    struct Edge{int u, v;};
    vector <Edge> G[M];
    struct Node{
        int id, mi, mx;
        bool operator < (const Node &rhs)const {
            return mi < rhs.mi || (mi == rhs.mi && mx < rhs.mx);
        }
    };
    vector <Node> row[M], lie[M];
    struct Init{int xs,ys,xe,ye;}p[M];
    
    int find(int x){
        if(x == fa[x]) return x;
        return fa[x] = find(fa[x]);
    }
    void uni(int x, int y){
        int fx = find(x), fy = find(y);
        if(fx != fy) mix++, fa[fx] = fy;
    }
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*=f;    
    }
    int main(){
        freopen("building.in","r",stdin);
        freopen("building.out","w",stdout);
        int cas;
        scanf("%d", &cas);
        int n, m, k, Q;
        int xs,ys,ye,xe;
        scanf("%d%d%d%d", &n, &m, &k, &Q);
        For(i, 1, k){
            xs = read(), ys = read(), xe = read(), ye = read();
            p[i] = (Init){xs,ys,xe,ye};
            if(xs == xe) sum[xs] += ye - ys + 1;
            else cf[xs]++, cf[xe+1]--;
            row[xs].push_back((Node){i, ys, ye});
            lie[ys].push_back((Node){i, xs, xe});
        }
        For(i, 1, n) sort(row[i].begin(), row[i].end());
        For(i, 1, m) sort(lie[i].begin(), lie[i].end());
        
        For(i, 1, k){
            int dwn    = p[i].xe + 1;
            int pos = upper_bound(row[dwn].begin(), row[dwn].end(), (Node){0, p[i].ye, m+1}) - row[dwn].begin() - 1;
            for(; pos >= 0 && row[dwn][pos].mx >= p[i].ys; pos--)
                G[dwn].push_back((Edge){i, row[dwn][pos].id});
                
            int rg = p[i].ye + 1;
            pos = upper_bound(lie[rg].begin(), lie[rg].end(), (Node){0, p[i].xe, n+1}) - lie[rg].begin() - 1;
            for(; pos >= 0 && lie[rg][pos].mx >= p[i].xs; pos--)
                G[max(p[i].xs, lie[rg][pos].mi)].push_back((Edge){i, lie[rg][pos].id});    
        }
        int tot = 0;
        For(i, 1, k) fa[i] = i;
        For(i, 1, n){
            tot += row[i].size();
            int siz = G[i].size();
            For(j, 0, siz-1){
                int u = G[i][j].u, v = G[i][j].v;
                uni(u, v);
            }
            scc[i] = tot - mix; 
        }
        
        For(i, 1, n) cf[i] += cf[i-1];
        For(i, 1, n){
            cf[i] += cf[i-1];
            sum[i] += sum[i-1];
            ans[i] = sum[i] + cf[i];
        } 
        
        while(Q--){
            int opt, u;
            opt = read(), u = read();
            printf("%d
    ", opt ? scc[u] : ans[u]);
        }
    }
    View Code
  • 相关阅读:
    sshd
    eclipse运行报java.lang.OutOfMemoryError: PermGen space解决方法
    项目之间依赖
    shell-
    部署记录
    mysql index使用
    GitHub上搭建私人hexo博客操作教程
    关于Vue实例的生命周期(2)
    JS中的五种去重方法
    Vue入门教程(2)
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9774206.html
Copyright © 2011-2022 走看看