zoukankan      html  css  js  c++  java
  • 7.3模拟赛

    T1.manage [LUOGU]P2920

    按结束时间排序,贪心即可。

    T2.software [BZOJ] 2427

    每个软件只依赖一个软件,和《软件包管理器》的描述非常像,但这里没有特别声明,是可以构成环的。

    一个环上只能所有软件同时都安装或者不安装,所以考虑把环缩成一个点

    Tarjan缩点后,就是一个树上背包问题了。

    我们可以把子树泛化成物品,本质上是一个分组背包。

    代码见附录①。

    T3.rebuild [BZOJ] 2957

             首先将楼房属性(位置x,高度y)转化为斜率y/x,我们要求的是一个斜率递增序列的长度。

           用线段树解决,考虑维护区间最长序列长度len (是不是二维偏序序列长度都能用线段树?)

           查询操作,就是len[root]

           修改操作,就是单点修改的问题,在回溯时,考虑如何进行pushup操作。

           记当前节点为cur,左右儿子分别为ls,rs

           1:记录区间斜率最大值mx和最小值mn,进行分类讨论。        

    1.    mx[ls]<mn[rs],可以直接合并两个区间。

    2.    mn[ls]>mx[rs],右区间全部被遮挡,只留左区间。

    3.    otherwise,在右区间二分mx[ls]的位置pos,合并左区间和右区间[pos,r]部分。

    2:记录区间斜率最大值mx

           右区间的最大值一定有机会成为最大值,mx[cur]=max(mx[ls],mx[rs])

           对于len,直接将mx[ls]在右区间进行二分即可。

          

    一点细节,二分中,当w<mx[cur]时返回query(ls,l,mid,w)+len[cur]-len[ls]

    这里一定是len[cur]-len[ls],它和len[rs]不等价!

            


    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    
    using namespace std; 
    
    const int MAXN=100005;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    struct Node{
        int lon,tim;
    }nodes[MAXN];
    bool cmp(const Node &x,const Node &y){
        return x.tim<y.tim;
    }
    
    int n;
    
    int main(){
        n=rd();
        for(int i=1;i<=n;i++){
            nodes[i].lon = rd();
            nodes[i].tim = rd();
        }
        sort(nodes+1,nodes+1+n,cmp);
        long long sum,mn=(1<<29),v;
        for(int i=1;i<=n;i++){
            sum+=nodes[i].lon;
            v=nodes[i].tim-sum;
            if(v<0) return puts("-1"),0;
            mn=min(mn,v);
        }
        printf("%lld",mn);
        return 0;
    }
     
    T1
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    const int MAXN=128;
    
    int n,m;
    int cost[MAXN],scost[MAXN];
    int val[MAXN],sval[MAXN];
    
    inline int rd(){
      int ret=0,f=1;char c;
      while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
      while(isdigit(c))ret=ret*10+c-'0',c=getchar();
      return ret*f;
    }
    
    struct Edge{
      int to[MAXN],nxt[MAXN];
      int ecnt,head[MAXN];
      #define M(a) memset(a,0,sizeof(a))
      Edge(){M(to);M(nxt);M(head);ecnt=0;}
      #undef M
      void add(int x,int y){
        to[++ecnt]=y;
        nxt[ecnt]=head[x];
        head[x]=ecnt;
      }
    }e1,e2;
    int ind[MAXN];
    
    int scc[MAXN],cnt;
    int dfn[MAXN],low[MAXN],tim;
    int sta[MAXN],ins[MAXN],top;
    void tarjan(int x){
      dfn[x]=low[x]=++tim;
      ins[sta[++top]=x]=1;
      for(int i=e1.head[x];i;i=e1.nxt[i]){
        int v=e1.to[i];
        if(!dfn[v]) {tarjan(v);low[x]=min(low[x],low[v]);}
        else if(ins[v]) low[x]=min(low[x],dfn[v]);
      }
      if(dfn[x]==low[x]){
        int elm=-1;cnt++;
        while(elm!=x){
          ins[elm=sta[top--]]=0;
          scc[elm]=cnt;
          scost[cnt]+=cost[elm];
          sval[cnt]+=val[elm];
        }
      }
    }
    
    int f[128][512];
    void dfs(int x){
       for(int i=e2.head[x];i;i=e2.nxt[i]){
         int v=e2.to[i];
         dfs(v);
         for(int j=m-scost[x];j>=0;j--)
           for(int k=0;k<=j;k++)
             f[x][j]=max(f[x][j],f[x][k]+f[v][j-k]);
       }
       for(int i=m;i>=0;i--)
         if(i>=scost[x]) f[x][i]=f[x][i-scost[x]]+sval[x];
         else f[x][i]=0;
    }
    
    int main(){
      n=rd();m=rd();
      for(int i=1;i<=n;i++) cost[i]=rd();
      for(int i=1;i<=n;i++) val[i]=rd();
      for(int i=1;i<=n;i++) e1.add(rd(),i);
      for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
      for(int i=1;i<=n;i++)
        for(int j=e1.head[i];j;j=e1.nxt[j]){
          int v=e1.to[j];
          if(scc[v]!=scc[i]) e2.add(scc[i],scc[v]),ind[scc[v]]++;
      }
      for(int i=1;i<=cnt;i++) if(!ind[i]) e2.add(cnt+1,i);
      dfs(cnt+1);
      cout<<f[cnt+1][m];
      return 0;
    }
    T2
    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
      int ret=0,f=1;char c;
      while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
      while(isdigit(c))ret=ret*10+c-'0',c=getchar();
      return ret*f;
    }
    
    const int MAXN=100005;
    int n,m;
    
    #define mid ((l+r)>>1)
    #define ls (cur<<1)
    #define rs (cur<<1|1)
    double mx[MAXN<<2],mn[MAXN<<2];
    int len[MAXN<<2];
    
    int query(int cur,int l,int r,double w){
      if(l==r) return mx[cur]>w;
      if(mx[ls]<=w) return query(rs,mid+1,r,w);
      return query(ls,l,mid,w)+len[cur]-len[ls];
    }
    
    void pushup(int cur,int l,int r){
        mx[cur]=max(mx[ls],mx[rs]);
      len[cur]=len[ls]+query(rs,mid+1,r,mx[ls]);
    }
    
    void update(int x,int cur,int l,int r,double w){
        if(l==r){mx[cur]=w;len[cur]=1;return;}
        if(x<=mid) update(x,ls,l,mid,w);
        if(mid <x) update(x,rs,mid+1,r,w);
        pushup(cur,l,r);
    }
    
    int main(){
        n=rd();m=rd();
        int x,y;
        for(int i=1;i<=m;i++){
            x=rd();y=rd();
            double d=1.0*y/x;
            update(x,1,1,n,d);
            printf("%d
    ",len[1]);
        }
        return 0;
    }
    T3

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9260570.html

  • 相关阅读:
    centos8 将SSSD配置为使用LDAP并要求TLS身份验证
    Centos8 搭建 kafka2.8 .net5 简单使用kafka
    .net core 3.1 ActionFilter 拦截器 偶然 OnActionExecuting 中HttpContext.Session.Id 为空字符串 的问题
    Springboot根据不同环境加载对应的配置
    VMware Workstation12 安装 Centos8.3
    .net core json配置文件小结
    springboot mybatisplus createtime和updatetime自动填充
    .net core autofac依赖注入简洁版
    .Net Core 使用 redis 存储 session
    .Net Core 接入 RocketMQ
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9260570.html
Copyright © 2011-2022 走看看