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

  • 相关阅读:
    通过抓包软件Charles和Fiddle快速模拟(Mock)数据
    截图+贴图工具 Snipaste
    二、Vuex State
    一、Vuex 的概念及安装使用
    一、记录Git使用中遇到的问题及解决方法
    编译Less文件
    Less的基本使用
    二、Git基础操作
    三、Git常用命令
    sql server 自增长字段,标识值重置
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9260570.html
Copyright © 2011-2022 走看看