• 10.8 模拟赛


    非常的菜 被初中踩成了弱智

    T1 game

    题目大意:

    n轮游戏 在第$i$轮已经获胜$j$轮继续获胜的概率为 p i j

    每一轮可以选择放弃(即100%失败)

    求最优策略下 获胜场数的期望

    思路:

    可以发现并不需要放弃

    直接dp即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 1100
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 //yyc score=0
    22 int n;
    23 double a[MAXN][MAXN],dp[MAXN][MAXN],ans;
    24 int main()
    25 {
    26     freopen("game.in","r",stdin);
    27     freopen("game.out","w",stdout);
    28     n=read();
    29     for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) scanf("%lf",&a[i][j]);
    30     dp[1][1]=1.0;
    31     for(int i=2;i<=n+1;i++) for(int j=1;j<=i;j++)
    32         dp[i][j]=dp[i-1][j]*(1.0-a[i-1][j])+dp[i-1][j-1]*a[i-1][j-1];
    33     for(int i=1;i<=n+1;i++) ans+=(i-1)*dp[n+1][i];
    34     printf("%.2lf",ans);
    35 }
    View Code

    T2 cake 

    题目大意:

    n个物品 每个物品体积即背包$le 10^9$ 求背包内最大体积

    思路:

    本来是一个折半搜索裸题

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define M 1200020
     4 using namespace std;
     5 namespace IO{
     6     const int BS=(1<<20)+5; int Top=0;
     7     char Buffer[BS],OT[BS],*OS=OT,*HD,*TL,SS[20]; const char *fin=OT+BS-1;
     8     char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);} return (HD==TL)?EOF:*HD++;}
     9     void flush(){fwrite(OT,1,OS-OT,stdout);}
    10     void Putchar(char c){*OS++ =c;if(OS==fin)flush(),OS=OT;}
    11     void write(int x){
    12         if(!x){Putchar('0');return;} if(x<0) x=-x,Putchar('-');
    13         while(x) SS[++Top]=x%10,x/=10;
    14         while(Top) Putchar(SS[Top]+'0'),--Top;
    15     }
    16     int read(){
    17         int nm=0,fh=1; char cw=getchar();
    18         for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
    19         for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
    20         return nm*fh;
    21     }
    22 }using namespace IO;
    23 int n,m,val[50][2],p[2][M],maxn,tp[2],sz[2],ans;
    24 void dfs(int pos,int now,int kd){
    25     if(now>m) return;
    26     if(pos==tp[kd]+1){p[kd][++sz[kd]]=now;return;}
    27     dfs(pos+1,now,kd),dfs(pos+1,now+val[pos][kd],kd);
    28 }
    29 int main(){
    30     freopen("cake.in","r",stdin);
    31     freopen("cake.out","w",stdout);
    32     n=read(),m=read(),ans=m;
    33     for(int i=1;i<=n;i++) val[++tp[i&1]][i&1]=read();
    34     dfs(1,0,0),sort(p[0]+1,p[0]+sz[0]+1);
    35     dfs(1,0,1),sort(p[1]+1,p[1]+sz[1]+1);
    36     for(int i=0,j=sz[1];i<=sz[0];i++){
    37         while(j>0&&p[0][i]+p[1][j]>m) j--;
    38         ans=min(ans,m-p[0][i]-p[1][j]);
    39     }printf("%d
    ",ans);return 0;
    40 }
    View Code

    但是我非常菜的直接dfs剪枝得了90分

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 50
    13 #define MOD 1000000007
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 //yyc score=0
    23 int n,m,a[MAXN],ans=inf,s[MAXN];
    24 map <int,bool> vis;
    25 void dfs(int x,int sum)
    26 {
    27     //cout<<x<<" "<<sum+a[x]<<endl;
    28     if(sum+a[x]>m||vis[sum+a[x]]) return ;vis[sum+a[x]]=1,ans=min(ans,m-sum-a[x]);
    29     if(x==1) {ans=min(ans,m-sum-a[x]);return ;}
    30     if(sum+s[1]-s[x+1]<=m) {ans=min(ans,m-sum-s[1]+s[x+1]);return ;}
    31     for(int i=x-1;i;i--)
    32         if(sum+a[x]+a[i]<=m) dfs(i,sum+a[x]);
    33 }
    34 int main()
    35 {
    36     freopen("cake.in","r",stdin);
    37     freopen("cake.out","w",stdout);
    38     n=read(),m=read();
    39     for(int i=1;i<=n;i++) a[i]=read();
    40     sort(a+1,a+n+1);
    41     for(int i=n;i;i--) s[i]=s[i+1]+a[i];
    42     vis[0]=1;
    43     for(int i=n;i;i--) dfs(i,0);
    44     printf("%d
    ",ans);
    45 }
    View Code

    T3 grid

    题目大意:

    一个矩阵 规定一些子矩阵内最大值为k 求满足条件矩阵的方案数

    思路:

    离散化之后处理每个矩阵的大小

    然后容斥

    (std)

     1 #include<bits/stdc++.h>
     2 typedef long long i64;
     3 const int P=1e9+7;
     4 int T,h,w,m,n;
     5 int xs[33],ys[33],xp,yp,vs[33],vp,ts[33];
     6 int rc[33][5],mv[33][33],as[33][33];
     7 void mins(int&a,int b){if(a>b)a=b;}
     8 int pw(int a,int n){
     9     int v=1;
    10     for(;n;n>>=1,a=i64(a)*a%P)if(n&1)v=i64(v)*a%P;
    11     return v;
    12 }
    13 int main(){
    14     int ans=0;
    15     scanf("%d%d%d%d",&h,&w,&m,&n);
    16     xp=yp=vp=0;
    17     xs[xp++]=1;
    18     xs[xp++]=h+1;
    19     ys[yp++]=1;
    20     ys[yp++]=w+1;
    21     vs[vp++]=m;
    22     for(int i=0;i<n;++i){
    23         for(int j=0;j<5;++j)scanf("%d",rc[i]+j);
    24         xs[xp++]=rc[i][0];
    25         xs[xp++]=rc[i][2]+1;
    26         ys[yp++]=rc[i][1];
    27         ys[yp++]=rc[i][3]+1;
    28         vs[vp++]=rc[i][4];
    29         vs[vp++]=rc[i][4]-1;
    30     }
    31     std::sort(xs,xs+xp);
    32     xp=std::unique(xs,xs+xp)-xs-1;
    33     std::sort(ys,ys+yp);
    34     yp=std::unique(ys,ys+yp)-ys-1;
    35     std::sort(vs,vs+vp);
    36     vp=std::unique(vs,vs+vp)-vs;
    37     for(int i=0;i<xp;++i)
    38     for(int j=0;j<yp;++j)as[i][j]=(xs[i+1]-xs[i])*(ys[j+1]-ys[j]);
    39     for(int t=0;t<n;++t){
    40         rc[t][0]=std::lower_bound(xs,xs+xp,rc[t][0])-xs;
    41         rc[t][2]=std::lower_bound(xs,xs+xp,rc[t][2]+1)-xs;
    42         rc[t][1]=std::lower_bound(ys,ys+yp,rc[t][1])-ys;
    43         rc[t][3]=std::lower_bound(ys,ys+yp,rc[t][3]+1)-ys;
    44         rc[t][4]=std::lower_bound(vs,vs+vp,rc[t][4])-vs;
    45     }
    46     for(int S=0;S<(1<<n);++S){
    47         for(int i=0;i<xp;++i)
    48         for(int j=0;j<yp;++j)mv[i][j]=vp-1;
    49         int s=1;
    50         for(int t=0;t<n;++t){
    51             int v=rc[t][4];
    52             if(S>>t&1)s=-s,--v;
    53             for(int i=rc[t][0];i<rc[t][2];++i)
    54             for(int j=rc[t][1];j<rc[t][3];++j)mins(mv[i][j],v);
    55         }
    56         for(int i=0;i<vp;++i)ts[i]=0;
    57         for(int i=0;i<xp;++i)
    58         for(int j=0;j<yp;++j)ts[mv[i][j]]+=as[i][j];
    59         for(int i=0;i<vp;++i)s=i64(s)*pw(vs[i],ts[i])%P;
    60         ans=(ans+s)%P;
    61     }
    62     printf("%d
    ",(ans+P)%P);
    63     return 0;
    64 }
    View Code

    T4 road

    题目大意:

    一棵树 一个点S 

    Q次独立的询问 每次可以从S修一条简单路径使该路径上边权为0 求修改后 a - b 上路径权值和最小

    思路:

    由于边权可能为负 以S为根建树 每次只能从lca(a,b)引一条最长的链 所以用倍增维护每个点向上连续的最小值

    查询的时候判断链是向左还是向右即可

    (由于min设成了inf导致挂掉了)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<vector>
     9 #define ll long long
    10 #define MAXN 200100
    11 #define inf 2139062143
    12 using namespace std;
    13 inline int read()
    14 {
    15     int f=1,x=0;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0',ch=getchar();}
    18     return x*f;
    19 }
    20 int n,q,s,cnt,tot,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],val[MAXN<<1];
    21 int dep[MAXN],f[MAXN][22],g[MAXN][22],dis[MAXN],sz[MAXN],hsh[MAXN];
    22 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
    23 void dfs(int x,int fa)
    24 {
    25     sz[x]=1,hsh[x]=++tot;
    26     for(int i=1;(1<<i)<=dep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
    27     for(int i=1;(1<<i)<=dep[x];i++) g[x][i]=min(g[x][i-1],dis[x]-dis[f[x][i-1]]+g[f[x][i-1]][i-1]);
    28     for(int i=fst[x];i;i=nxt[i])
    29         if(to[i]!=fa)
    30         {
    31             f[to[i]][0]=x,dep[to[i]]=dep[x]+1,dis[to[i]]=dis[x]+val[i];
    32             if(val[i]<0) g[to[i]][0]=val[i];
    33             dfs(to[i],x);sz[x]+=sz[to[i]];
    34         }
    35 }
    36 int lca(int u,int v)
    37 {
    38     if(dep[u]<dep[v]) swap(u,v);int t=dep[u]-dep[v];
    39     for(int i=21;i>=0;i--) if((1<<i)&t) u=f[u][i];
    40     if(u==v) return u;
    41     for(int i=21;i>=0;i--)
    42         if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
    43     return f[u][0];
    44 }
    45 int work(int x,int anc)
    46 {
    47     int t=dep[x]-dep[anc],tmp=0,res=0;
    48     for(int i=21;i>=0;i--)
    49         if((1<<i)&t)
    50             res=min(res,tmp+g[x][i]),
    51             tmp+=dis[x]-dis[f[x][i]],x=f[x][i];
    52     return res;
    53 }
    54 int main()
    55 {
    56     freopen("road.in","r",stdin);
    57     freopen("road.out","w",stdout);
    58     n=read(),q=read(),s=read();int a,b,c,l3,res,sum;
    59     for(int i=1;i<n;i++) {a=read(),b=read(),c=read();add(a,b,c);add(b,a,c);}
    60     dfs(s,0);
    61     while(q--)
    62     {
    63         a=read(),b=read(),c=lca(a,b),res=sum=dis[a]+dis[b]-(dis[c]<<1);
    64         printf("%d
    ",min(work(a,c)+dis[b]-dis[c],work(b,c)+dis[a]-dis[c]));
    65     }
    66 }
    View Code

    T5 bride

    题目大意:

    思路:

    爆搜然后状态压缩计算答案

    (不过好像题目锅了)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<vector>
     9 #define ll long long
    10 #define MAXN 200100
    11 #define inf 2139062143
    12 using namespace std;
    13 inline int read()
    14 {
    15     int f=1,x=0;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0',ch=getchar();}
    18     return x*f;
    19 }
    20 int n,k,A,w[15],h[15],a[15],t[15],q[15],r,tmp[15];
    21 double ans=1.0;
    22 void solve()
    23 {
    24     for(int i=1;i<=n;i++) tmp[i]=max(0,h[i]-10*a[i]);
    25     double res=0.0,p;int cnt=0,sum=0;r=0;
    26     for(int i=1;i<=n;i++)
    27         if(tmp[i]>0) q[r++]=i;
    28     for(int i=0;i<(1<<r);i++)
    29     {
    30         p=1.0;cnt=sum=0;
    31         for(int j=0;j<r;j++)
    32             if((1<<j)&i) p*=tmp[q[j]]/100.0,cnt++,sum+=w[q[j]];
    33             else p*=(1.0-tmp[q[j]]/100.0);
    34         if(cnt>(n/2)) res+=(p*((double)sum/(sum+A)));
    35     }
    36     ans=min(ans,res);
    37 }
    38 void dfs(int x,int rst)
    39 {
    40     if(x==n||rst==0) {for(int i=x;i<=n;i++) a[i]=rst;solve();return ;}
    41     for(int i=0;i<=rst;i++) {a[x]=i;dfs(x+1,rst-i);}
    42 }
    43 int main()
    44 {
    45     freopen("bride.in","r",stdin);
    46     freopen("bride.out","w",stdout);
    47     n=read(),k=read(),A=read();
    48     for(int i=1;i<=n;i++) w[i]=read(),h[i]=read();
    49     dfs(1,k);printf("%.6lf",ans);
    50 }
    View Code

    T6 climb

    题目大意:

    一些人在树上走 每个人在树上走了一些链(从根开始)

    求每个点分别为多少个人经过

    思路:

    对于每个人相当于对链并+1 由于只查询一次 只需要树上差分 

    按照dfs序排序 对相邻的两个的lca -1

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<vector>
     9 #define ll long long
    10 #define MAXN 200100
    11 #define inf 2139062143
    12 using namespace std;
    13 inline int read()
    14 {
    15     int f=1,x=0;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0',ch=getchar();}
    18     return x*f;
    19 }
    20 int n,m,cnt,tot,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1];
    21 int dep[MAXN],fa[MAXN],sz[MAXN],hsh[MAXN],bl[MAXN];
    22 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    23 void dfs(int x)
    24 {
    25     sz[x]=1;
    26     for(int i=fst[x];i;i=nxt[i])
    27         if(to[i]!=fa[x])
    28         {
    29             dep[to[i]]=dep[x]+1;dfs(to[i]);sz[x]+=sz[to[i]];
    30         }
    31 }
    32 void dfs(int x,int anc)
    33 {
    34     bl[x]=anc,hsh[x]=++tot;int hvs=0;
    35     for(int i=fst[x];i;i=nxt[i])
    36         if(to[i]!=fa[x]&&sz[to[i]]>sz[hvs]) hvs=to[i];
    37     if(!hvs) return ;dfs(hvs,anc);
    38     for(int i=fst[x];i;i=nxt[i])
    39         if(to[i]!=fa[x]&&to[i]!=hvs) dfs(to[i],to[i]);
    40 }
    41 struct Ask {int pos,val;}g[MAXN];
    42 bool cmp(Ask a,Ask b) {return a.val<b.val||(a.val==b.val&&hsh[a.pos]<hsh[b.pos]);}
    43 int lca(int u,int v) 
    44 {
    45     while(bl[u]!=bl[v]) {if(dep[bl[u]]<dep[bl[v]]) swap(u,v);u=fa[bl[u]];}
    46     return dep[u]>dep[v]?v:u;
    47 }
    48 int sum[MAXN];
    49 void work(int x)
    50 {
    51     for(int i=fst[x];i;i=nxt[i]) if(to[i]!=fa[x]) {work(to[i]);sum[x]+=sum[to[i]];}
    52 }
    53 int main()
    54 {
    55     freopen("climb.in","r",stdin);
    56     freopen("climb.out","w",stdout);
    57     n=read(),m=read();
    58     for(int i=2;i<=n;i++) {fa[i]=read()+1;add(i,fa[i]);add(fa[i],i);}
    59     for(int i=1;i<=m;i++) g[i].pos=read()+1,g[i].val=read();
    60     dfs(1);dfs(1,1);sort(g+1,g+m+1,cmp);
    61     for(int i=1,tmp=1;i<=m;tmp=++i)
    62     {
    63         while(g[i].val==g[i+1].val&&i<=m) i++;
    64         for(int j=tmp;j<=i;j++) sum[g[j].pos]++;
    65         for(int j=tmp;j<i;j++) sum[lca(g[j].pos,g[j+1].pos)]--;
    66     }
    67     work(1);
    68     for(int i=1;i<=n;i++) printf("%d
    ",sum[i]);
    69 }
    View Code

    或者说是线段树合并裸题

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<vector>
     8 #define maxm 200004
     9 #define maxn 100005
    10 using namespace std;
    11 int read() {
    12     int x=0,f=1;char ch=getchar();
    13     for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    14     for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    15     return x*f;
    16 }
    17 vector<int> pt[maxn];
    18 int n,m;
    19 struct seg{int son[2],sum;bool val;}t[maxn*40];
    20 int rt[maxn],fg[maxn];
    21 struct Edge {int to,nxt;}e[maxm];
    22 int head[maxn],cnt;
    23 void add(int u,int v) {e[cnt].nxt=head[u];e[cnt].to=v;head[u]=cnt++;return;}
    24 int merge(int x,int y) {
    25     if(!x) return y;if(!y) return x;
    26     if(t[x].sum<t[y].sum) swap(x,y);
    27     if(t[x].val) {return x;}
    28     t[x].son[0]=merge(t[x].son[0],t[y].son[0]);
    29     t[x].son[1]=merge(t[x].son[1],t[y].son[1]);
    30     t[x].sum=t[t[x].son[0]].sum+t[t[x].son[1]].sum;
    31     t[x].val=t[t[x].son[0]].val&t[t[x].son[1]].val;
    32     return x;
    33 }
    34 int hsh[maxn],tot,d[maxn],g[maxn],sz,ans[maxn];
    35 void add(int &x,int l,int r,int pos) {
    36     if(!x) x=++sz,t[sz]=t[x];
    37     if(l==r) {t[x].val=1;t[x].sum=1;return;}
    38     int mid=(l+r)>>1;
    39     if(pos<=mid) {add(t[x].son[0],l,mid,pos);}
    40     else {add(t[x].son[1],mid+1,r,pos);}
    41     t[x].sum=t[t[x].son[0]].sum+t[t[x].son[1]].sum;t[x].val=t[t[x].son[0]].val&t[t[x].son[1]].val;
    42     return;
    43 }
    44 void dfs(int x,int pre) {
    45     if(fg[x]) for(int i=0;i<fg[x];i++) add(rt[x],1,tot,pt[x][i]);
    46     for(int i=head[x];i>=0;i=e[i].nxt) {
    47         int to=e[i].to;if(to==pre) continue;
    48         dfs(to,x);rt[x]=merge(rt[x],rt[to]);
    49     }
    50     ans[x]=t[rt[x]].sum;
    51 }
    52 int main() {
    53     freopen("climb.in","r",stdin);
    54     freopen("climb.out","w",stdout);
    55     memset(head,-1,sizeof(head));
    56     n=read(),m=read();
    57     for(int i=2;i<=n;i++) {
    58         int tmp=read()+1;
    59         add(i,tmp);add(tmp,i);
    60     }
    61     for(int i=1;i<=m;i++) {
    62         d[i]=read()+1;g[i]=read();
    63         hsh[++tot]=g[i];
    64     }
    65     sort(hsh+1,hsh+tot+1);
    66     tot=unique(hsh+1,hsh+tot+1)-hsh-1;
    67     for(int i=1;i<=m;i++) {
    68         g[i]=lower_bound(hsh+1,hsh+tot+1,g[i])-hsh;
    69         pt[d[i]].push_back(g[i]);
    70         fg[d[i]]++;
    71     }
    72     dfs(1,0);
    73     for(int i=1;i<=n;i++) printf("%d
    ",ans[i]);
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    (转)使用 sys 帳號登入 E900 Standalone 安裝的 Oracle 資料庫
    Eclipse中main函数由控制台输入参数为空的处理
    orcle10Concepts笔记
    根据某个时间字符串获取上个月的时间
    eclipse导入java项目方法及出现问题
    好用的网址
    收藏网址
    Eclipse中main函数由控制台输入参数并接收
    java.io读写文本
    ClassNotFoundException处理
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9931866.html
Copyright © 2020-2023  润新知