• 无题2


    题解

    第一题:水

    #include<bits/stdc++.h>
    using namespace std;
    
    
    const int M = 1e5 + 5;
    
    struct Node{
        int s, t;
    }p[M];
    bool cmp(Node A, Node B){
        return A.t > B.t;
    }
    int main(){
        freopen("manage.in","r",stdin);
        freopen("manage.out","w",stdout);
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)scanf("%d%d", &p[i].s, &p[i].t);
        sort(p + 1, p + 1 + n, cmp);
        int now = p[1].t;
        p[n + 1].t = 1e9;
        for(int i = 1; i <= n; i++){
            now -= p[i].s;
            if(now > p[i + 1].t) now = p[i + 1].t;
        }
        printf("%d
    ", now >= 0 ? now : -1);
    }
    View Code

    第二题:先tarjan缩点,然后树上背包;我用的带权并查集,跑的分组背包,忽略了分叉的情况;

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 1e5 + 10;
    
    int v[M], w[M], V[M], W[M], fa[M], dp[305][M], idx, scc;
    int tot, place[M], h[M], dfn[M], low[M], d[M], siz[M], du[M]; 
    bool ins[M];
    struct edge{
        int v, nxt;
    }G[M];
    void add(int u, int v){
        G[++tot].nxt = h[u]; G[tot].v = v; h[u] = tot;
    }
    
    vector <int> group[M];
    stack <int> t;
    void tarjan(int u){
        dfn[u] = low[u] = ++idx;
        t.push(u); ins[u] = 1;
        
        int v = d[u];
        if(v){
            if(!dfn[v]){
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if(ins[v]) low[u] = min(low[u], dfn[v]);
        }
        
        
        if(low[u] == dfn[u]){
            scc++;
            while(1){
                int st = t.top(); t.pop();
                place[st] = scc;
                ins[st] = 0;
                if(st == u)break;
            }
        }
    }
    int n, m;
    void dfs(int u){
        dp[u][W[u]] = V[u];
        for(int i = h[u]; i; i = G[i].nxt){
            int v = G[i].v;
            dfs(v);
            for(int vv = m; vv >= W[u]; vv--)
                for(int p = 0; p <= vv; p++)
                    if(dp[u][vv - p] >= 0 && dp[v][p] >= 0)
                        dp[u][vv] = max(dp[u][vv], dp[u][vv - p] + dp[v][p]);
        }
        
        
    }
    
    
    int main(){
        freopen("software.in","r",stdin);
        freopen("software.out","w",stdout);
        
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) scanf("%d", &w[i]);
        for(int i = 1; i <= n; i++) scanf("%d", &v[i]);
        for(int i = 1; i <= n; i++) scanf("%d", &d[i]);
            
        for(int i = 1; i <= n; i++)
            if(!dfn[i]) tarjan(i);
        for(int i = 1; i <= n; i++){
            int u = place[i];
            V[u] += v[i]; W[u] += w[i];
            if(place[d[i]] != place[i])
                add(place[d[i]], place[i]), du[place[i]]++;
        }
        for(int i = 1; i <= scc; i++)
            if(!du[i])add(0, i);
        memset(dp, 0x8f, sizeof(dp));
        dfs(0);
        int ans = 0;
        for(int i = 0; i <= m; i++)ans = max(ans, dp[0][i]);
         printf("%d
    ", ans);
               
        
        
        
    } 
    View Code

    第三题:线段统计区间中递增的数, modify的神奇操作;

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e5 + 5;
    int n,val,pos,m;
    
    struct nd {    
        double val;
        int ans;
    }f[4 * N];
    
    int calc(int o,int l,int r,double val) {
        
        if(l == r) return f[o].val - val >= 1e-10;
        int mid = (l + r) >> 1;
        if(f[2 * o].val - val <= 1e-10) {
            return calc(2 * o + 1,mid + 1,r,val);
        }
        else {
            return f[o].ans - f[2 * o].ans + calc(2 * o,l,mid,val);
        }
    }
    
    void modify(int o,int l,int r,int pos,double val) {
        
        if(l == r) {
            f[o].val = val;
            f[o].ans = 1;
            return ;
        }
        int mid = (l + r) >> 1;
        if(pos <= mid) modify(2 * o,l,mid,pos,val);
        else modify(2 * o + 1,mid + 1,r,pos,val);
        f[o].val = max(f[2 * o].val,f[2 * o + 1].val);
        f[o].ans = f[2 * o].ans + calc(2 * o + 1,mid + 1,r,f[2 * o].val);
    }
    
    int main( ) {
        freopen("rebuild.in","r",stdin);
        freopen("rebuild.out","w",stdout);
        scanf("%d%d",& n,& m);
        while(m --) {
            scanf("%d%d",& pos,& val);
            modify(1,1,n,pos,1.0*val/pos);
            printf("%d
    ", f[1].ans);
        }
    }
    View Code
  • 相关阅读:
    python基础学习1-网络爬虫程序中的代理IP设置
    python基础学习1-翻译程序(连接到有道翻译网)
    python基础学习1-第一个网络爬虫程序
    python基础学习1-迭代器
    python基础学习1-列表推导式和字典推导式
    python基础学习1-类属性访问
    python基础学习1-描述符
    python基础学习2-easygui框架编程
    python基础学习1-计数器实例
    HDU2896 病毒侵袭
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9648570.html
Copyright © 2020-2023  润新知