3月部分题目简要题解

HDU算法题解析

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\n",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\n",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\n",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

 

转载于:https://www.cnblogs.com/phile/p/6566105.html

(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值