• 3月部分题目简要题解


    hdu5820

    官方题解:http://www.cnblogs.com/duoxiao/p/5777700.html

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 struct node{int l,r,s;} tr[500010*40];
     5 vector<int> g[50010];
     6 int pre[50010],h[50010],n,t;
     7 int build(int l,int r)
     8 {
     9     ++t; tr[t].s=0;
    10     if (l==r) return t;
    11     int m=(l+r)>>1,q=t;
    12     tr[t].l=build(l,m);
    13     tr[t].r=build(m+1,r);
    14     return q;
    15 }
    16 
    17 int ask(int i,int l,int r,int x,int y)
    18 {
    19     if (x>y) return 0;
    20     if (x<=l&&y>=r) return tr[i].s;
    21     else {
    22         int m=(l+r)>>1,s=0;
    23         if (x<=m) s+=ask(tr[i].l,l,m,x,y);
    24         if (y>m) s+=ask(tr[i].r,m+1,r,x,y);
    25         return s;
    26     }
    27 }
    28 
    29 int add(int i,int l,int r,int x)
    30 {
    31     ++t;
    32     if (l==r)
    33     {
    34         tr[t].s=tr[i].s+1;
    35         return t;
    36     }
    37     int m=(l+r)>>1,q=t;
    38     if (x<=m)
    39     {
    40         tr[q].r=tr[i].r;
    41         tr[q].l=add(tr[i].l,l,m,x);
    42     }
    43     else {
    44         tr[q].l=tr[i].l;
    45         tr[q].r=add(tr[i].r,m+1,r,x);
    46     }
    47     tr[q].s=tr[tr[q].l].s+tr[tr[q].r].s;
    48     return q;
    49 }
    50 
    51 
    52 bool check()
    53 {
    54     memset(pre,0,sizeof(pre));
    55     for (int i=1; i<=50000; i++)
    56     {
    57         h[i]=h[i-1];
    58         for (int j=0; j<g[i].size(); j++)
    59         {
    60             int l=(!j)?0:g[i][j-1];
    61             int r=(j==g[i].size()-1)?50001:g[i][j+1];
    62            // cout <<l<<" "<<r<<" "<<pre[g[i][j]]<<" "<<ask(h[i],1,50000,l+1,r-1)<<endl;
    63             if (ask(h[i],1,50000,l+1,r-1)!=ask(h[pre[g[i][j]]],1,50000,l+1,r-1)) return 0;
    64         }
    65         for (int j=0; j<g[i].size(); j++)
    66         {
    67             h[i]=add(h[i],1,50000,g[i][j]);
    68             pre[g[i][j]]=i;
    69         }
    70     }
    71     return 1;
    72 }
    73 
    74 int main()
    75 {
    76     scanf("%d",&n);
    77     t=0;
    78     h[0]=build(1,50000); int tmp=t;
    79     while (n)
    80     {
    81         t=tmp;
    82         for (int i=1; i<=n; i++)
    83         {
    84             int x,y;
    85             scanf("%d%d",&x,&y);
    86             g[x].push_back(y);
    87         }
    88         for (int i=1; i<=50000; i++)
    89         {
    90             sort(g[i].begin(),g[i].end());
    91             g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
    92         }
    93         if (check()) puts("YES"); else puts("NO");
    94         for (int i=1; i<=50000; i++) g[i].clear();
    95         scanf("%d",&n);
    96     }
    97 }
    View Code

    hdu5788

    官方题解:http://www.cnblogs.com/duoxiao/p/5777661.html

    其实有个简单的方法求子树的[t/2]名次:直接在dfs序上建立可持久化线段树查询即可

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 typedef long long ll;
      5 struct way{int po,next;} e[100010];
      6 struct node{int s,l,r;} tr[100010*40];
      7 int p[100010],l[100010],h[100010],w[100010],cur[100010],a[100010],r[100010],len,n,tot,t;
      8 ll c[100010],ans;
      9 void add(int x,int y)
     10 {
     11     e[++len].po=y;
     12     e[len].next=p[x];
     13     p[x]=len;
     14 }
     15 
     16 int build(int l,int r)
     17 {
     18     ++t; tr[t].s=0;
     19     if (l==r) return t;
     20     int m=(l+r)>>1,q=t;
     21     tr[t].l=build(l,m);
     22     tr[t].r=build(m+1,r);
     23     return q;
     24 }
     25 
     26 int mid(int a,int b,int l,int r,int k)
     27 {
     28     if (l==r) return l;
     29     else {
     30         int m=(l+r)>>1,s=tr[tr[b].l].s-tr[tr[a].l].s;
     31         if (k<=s) return mid(tr[a].l,tr[b].l,l,m,k);
     32         else return mid(tr[a].r,tr[b].r,m+1,r,k-s);
     33     }
     34 }
     35 
     36 int add(int i,int l,int r,int x)
     37 {
     38     ++t;
     39     if (l==r)
     40     {
     41         tr[t].s=tr[i].s+1;
     42         return t;
     43     }
     44     int m=(l+r)>>1,q=t;
     45     if (x<=m)
     46     {
     47         tr[q].r=tr[i].r;
     48         tr[q].l=add(tr[i].l,l,m,x);
     49     }
     50     else {
     51         tr[q].l=tr[i].l;
     52         tr[q].r=add(tr[i].r,m+1,r,x);
     53     }
     54     tr[q].s=tr[tr[q].l].s+tr[tr[q].r].s;
     55     return q;
     56 }
     57 
     58 void dfs1(int x)
     59 {
     60     l[x]=++tot; h[tot]=add(h[tot-1],1,100000,a[x]);
     61     for (int i=p[x]; i; i=e[i].next)
     62     {
     63         int y=e[i].po;
     64         dfs1(y);
     65     }
     66     w[x]=mid(h[l[x]-1],h[tot],1,100000,(tot-l[x]+2)/2);
     67     if (l[x]==tot) cur[x]=0; else cur[x]=mid(h[l[x]-1],h[tot],1,100000,(tot-l[x]+2)/2+1)-w[x];
     68 }
     69 
     70 void work(int x,int w)
     71 {
     72     for (int i=x; i; i-=i&(-i)) c[i]+=w;
     73 }
     74 
     75 ll ask(int x)
     76 {
     77     ll s=0;
     78     for (int i=x; i<=100000; i+=i&(-i)) s+=c[i];
     79     return s;
     80 }
     81 
     82 void dfs2(int x)
     83 {
     84     ll wh=(p[x]==0)?100000-a[x]:cur[x]-w[x];
     85     ans=max(ans,ask(a[x])+wh);
     86     if (cur[x]) work(w[x],cur[x]);
     87     for (int i=p[x]; i; i=e[i].next)
     88     {
     89         int y=e[i].po;
     90         dfs2(y);
     91     }
     92     if (cur[x]) work(w[x],-cur[x]);
     93 }
     94 
     95 int main()
     96 {
     97     t=0; h[0]=build(1,100000);
     98     int tmp=t;
     99     while (scanf("%d",&n)!=EOF)
    100     {
    101         t=tmp;
    102         len=0; memset(p,0,sizeof(p));
    103         for (int i=1; i<=n; i++) scanf("%d",&a[i]);
    104         for (int i=2; i<=n; i++)
    105         {
    106             int fa;
    107             scanf("%d",&fa);
    108             add(fa,i);
    109         }
    110         tot=0; h[1]=h[0]; dfs1(1);
    111         ll s=0;
    112         for (int i=1; i<=n; i++) s+=w[i];
    113      //   for (int i=1; i<=n; i++) cout <<"*"<<w[i]<<" "<<cur[i]<<endl;
    114         memset(c,0,sizeof(c)); ans=0;
    115         dfs2(1);
    116         printf("%lld
    ",ans+s);
    117     }
    118 }
    View Code

    hdu3605

    把n按照可选择方案二进制状态压缩,建图最大流即可

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 const int inf=1e9+7;
      5 struct way{int po,flow,next;} e[2400010];
      6 int t,n,p[2010],pre[2010],numh[2010],cur[2010],h[2010],d[2010],b[2010],m,len;
      7 
      8 void add(int x,int y,int f)
      9 {
     10      e[++len].po=y;
     11      e[len].flow=f;
     12      e[len].next=p[x];
     13      p[x]=len;
     14 }
     15 void build(int x, int y, int f)
     16 {
     17      add(x,y,f);
     18      add(y,x,0);
     19 }
     20 int sap()
     21 {
     22     memset(numh,0,sizeof(numh));
     23     memset(h,0,sizeof(h));
     24     numh[0]=t+1;
     25     for (int i=0; i<=t; i++) cur[i]=p[i];
     26     int j,u=0,s=0,neck=inf;
     27     while (h[0]<t+1)
     28     {
     29           d[u]=neck;
     30           bool ch=1;
     31           for (int i=cur[u]; i!=-1; i=e[i].next)
     32           {
     33               j=e[i].po;
     34               if (e[i].flow>0&&h[u]==h[j]+1)
     35               {
     36                  neck=min(neck,e[i].flow);
     37                  cur[u]=i;
     38                  pre[j]=u;  u=j;
     39                  if (u==t)
     40                  {
     41                     s+=neck;
     42                     while (u)
     43                     {
     44                           u=pre[u];
     45                           j=cur[u];
     46                           e[j].flow-=neck;
     47                           e[j^1].flow+=neck;
     48                     }
     49                     neck=inf;
     50                  }
     51                  ch=0;
     52                  break;
     53               }
     54           }
     55           if (ch)
     56           {
     57              if (--numh[h[u]]==0) return s;
     58              int q=-1,tmp=t;
     59              for (int i=p[u]; i!=-1; i=e[i].next)
     60              {
     61                  j=e[i].po;
     62                  if (e[i].flow&&h[j]<tmp)
     63                  {
     64                     tmp=h[j];
     65                     q=i;
     66                  }
     67              }
     68              cur[u]=q; h[u]=tmp+1;
     69              numh[h[u]]++;
     70              if (u)
     71              {
     72                 u=pre[u];
     73                 neck=d[u];
     74              }
     75           }
     76     }
     77     return s;
     78 }
     79 
     80 int main()
     81 {
     82     while (scanf("%d%d",&n,&m)!=EOF)
     83     {
     84         len=-1;
     85         memset(p,255,sizeof(p));
     86         memset(b,0,sizeof(b));
     87         for (int i=1; i<=n; i++)
     88         {
     89             int st=0,x;
     90             for (int j=0; j<m; j++)
     91             {
     92                 scanf("%d",&x);
     93                 st|=(x&1)<<j;
     94             }
     95             b[st]++;
     96         }
     97         t=(1<<m)+m+1;
     98         for (int i=0; i<(1<<m); i++)
     99         {
    100             for (int j=0; j<m; j++)
    101                 if ((i>>j)&1) build(i+m+1,j+1,b[i]);
    102             build(0,i+m+1,b[i]);
    103         }
    104         for (int i=1; i<=m; i++)
    105         {
    106             int x;
    107             scanf("%d",&x);
    108             build(i,t,x);
    109         }
    110         if (sap()==n) puts("YES"); else puts("NO");
    111     }
    112 }
    View Code

    hdu5988

    费用取对数,简单的费用流

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 using namespace std;
      6 struct way{int po,next,flow; double cost;} e[200010];
      7 const int inf=100000007;
      8 const double eps=1e-7;
      9 int pre[110],p[110],cur[110],q[4000010];
     10 double d[110];
     11 bool v[110];
     12 int len,n,m,t,k;
     13 
     14 void add(int x,int y,int f,double c)
     15 {
     16      e[++len].po=y;
     17      e[len].flow=f;
     18      e[len].cost=c;
     19      e[len].next=p[x];
     20      p[x]=len;
     21 }
     22 
     23 void build(int x,int y, int f, double c)
     24 {
     25      add(x,y,f,c);
     26      add(y,x,0,-c);
     27 }
     28 
     29 bool spfa()
     30 {
     31      int f=1,r=1;
     32      for (int i=1; i<=t; i++) d[i]=inf;
     33      memset(v,0,sizeof(v));
     34      d[0]=0; q[1]=0;
     35      while (f<=r)
     36      {
     37            int x=q[f++];
     38            v[x]=0;
     39            for (int i=p[x]; i!=-1; i=e[i].next)
     40            {
     41                int y=e[i].po;
     42                if (e[i].flow&&d[x]+e[i].cost+eps<d[y])
     43                {
     44                   d[y]=d[x]+e[i].cost;
     45                   pre[y]=x; cur[y]=i;
     46                   if (!v[y])
     47                   {
     48                      q[++r]=y;
     49                      v[y]=1;
     50                   }
     51                }
     52            }
     53      }
     54      return d[t]<inf;
     55 }
     56 
     57 double mincost()
     58 {
     59     int j;
     60     double s=0;
     61     while (spfa())
     62     {
     63           int neck=inf;
     64           for (int i=t; i; i=pre[i])
     65           {
     66               j=cur[i];
     67               neck=min(neck,e[j].flow);
     68           }
     69           s+=d[t]*neck;
     70           for (int i=t; i; i=pre[i])
     71           {
     72               j=cur[i];
     73               e[j].flow-=neck;
     74               e[j^1].flow+=neck;
     75           }
     76     }
     77     return s;
     78 }
     79 
     80 int main()
     81 {
     82     int cas;
     83     scanf("%d",&cas);
     84     while (cas--)
     85     {
     86         scanf("%d%d",&n,&m);
     87         t=n+1; len=-1; memset(p,255,sizeof(p));
     88         for (int i=1; i<=n; i++)
     89         {
     90             int x,y;
     91             scanf("%d%d",&x,&y);
     92             if (x-y>0) build(0,i,x-y,0);
     93             else if (x-y<0) build(i,t,y-x,0);
     94         }
     95         for (int i=1; i<=m; i++)
     96         {
     97             int x,y,f; double c;
     98             scanf("%d%d%d%lf",&x,&y,&f,&c);
     99             c=-log2(1.0-c);
    100             if (f) build(x,y,1,0);
    101             if (f>1) build(x,y,f-1,c);
    102         }
    103         double ans=mincost();
    104         ans=pow(2,-ans);
    105         printf("%.2lf
    ",1.0-ans);
    106     }
    107 }
    View Code

    hdu5985

    无穷项一般要么高斯消元要么取有限项保留对应精度即可,这里只要求出h[i][k]表示第i个在第k次操作后被全部移走的概率就可以轻易计算出答案

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 double h[15][80],ans[15],p[15];
     5 int a[15],n;
     6 int main()
     7 {
     8     int cas;
     9     scanf("%d",&cas);
    10     while (cas--)
    11     {
    12         scanf("%d",&n);
    13         for (int i=1; i<=n; i++)
    14             scanf("%d%lf",&a[i],&p[i]);
    15         if (n==1)
    16         {
    17             printf("%.6lf
    ",1.0);
    18             continue;
    19         }
    20         for (int i=1; i<=n; i++)
    21         {
    22             double tmp=1.0;
    23             for (int j=1; j<=76; j++)
    24             {
    25                 tmp*=p[i];
    26                 h[i][j]=pow(1-tmp,a[i]);
    27             }
    28         }
    29         for (int i=1; i<=n; i++)
    30         {
    31             ans[i]=0;
    32             for (int k=1; k<=75; k++)
    33             {
    34                 double tmp=1.0;
    35                 for (int j=1; j<=n; j++)
    36                     if (j!=i) tmp*=h[j][k];
    37                 ans[i]+=(h[i][k+1]-h[i][k])*tmp;
    38             }
    39         }
    40         for (int i=1; i<=n; i++)
    41         {
    42             printf("%.6lf",ans[i]);
    43             if (i==n) puts(""); else printf(" ");
    44         }
    45     }
    46 }
    View Code
  • 相关阅读:
    【elasticsearch】关于elasticSearch的基础概念了解【转载】
    【docker】docker容器和宿主机之间文件互传,互相拷贝
    【spring cloud】【docker】使用docker在centOS上部署spring cloud微服务架构服务
    【spring cloud】【IDEA】【Maven】spring cloud多模块打包,打包的jar包只有几k,jar包无法运行,运行报错:no main manifest attribute, in /ms-eureka.jar
    【spring cloud】【IDEA】【maven】spring cloud多模块在idea上使用maven插件打包报错:程序包XXX不存在
    【linux】linux重启tomcat + 实时查看tomcat启动日志
    【linux】linux查看文件大小,磁盘大小,ls命令的使用
    【spring cloud】在spring cloud服务中,打包ms-core失败,报错Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.4.RELEASE:repackage (default) on project
    【微信小程序】微信小程序 文本过长,自动换行的问题
    【linux】centos7终端中文显示乱码,命令返回中文乱码
  • 原文地址:https://www.cnblogs.com/phile/p/6566105.html
Copyright © 2020-2023  润新知