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

    T1 sort

    题目大意:

    $n$个人,每个人有一个分,$m$对关系,表示两个人的分数关系,已知关系中每个人最多有一个人的分比他小

    求满足条件的所有人的排名有多少种

    思路:

    容易发现若没有$=$号则使用组合数就可以非常简单的合并子树

    若有两个等级数为$i,j$ 我们可以枚举最终的等级数$k$,设这样的方案数为$d(i,j,k)$ 则$dp[u][k]+=dp[x][i]*dp[v][j]*d(i,j,k)$

    在dp之前 我们预处理$d$数组就可以使复杂度满足

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define ull unsigned long long
     4 #define db double
     5 #define inf 2139092143
     6 #define MAXN 510
     7 #define MOD 998244353
     8 #define rep(i,s,t) for(register int i=(s),i##end=(t);i<=i##end;++i)
     9 #define dwn(i,s,t) for(register int i=(s),i##end=(t);i>=i##end;--i)
    10 #define ren for(int i=fst[x];i;i=nxt[i])
    11 #define pls(a,b) (a+b)%MOD
    12 #define mns(a,b) (a-b+MOD)%MOD
    13 #define mul(a,b) (1LL*a*b)%MOD
    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 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,vis[MAXN],fa[MAXN];
    23 int d[MAXN][MAXN][MAXN],f[MAXN][MAXN],t[MAXN][MAXN],ind[MAXN],sz[MAXN];
    24 struct opt{int u,v,t;}q[MAXN];
    25 int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}
    26 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,ind[v]++;}
    27 void pe(int &a,int b) {a=pls(a,b);}
    28 int dfs(int x)
    29 {
    30     if(vis[x]<0) return 0;vis[x]=-1;
    31     ren if(!vis[to[i]]&&!dfs(to[i])) return 0;else if(vis[to[i]]<0) return 0;
    32     vis[x]=1;return 1;
    33 }
    34 void dp(int x)
    35 {
    36     f[x][1]=sz[x]=1;ren if(to[i]!=x)
    37     {
    38         dp(to[i]);rep(j,1,sz[x]) rep(k,1,sz[to[i]]) rep(o,max(j,k),j+k)
    39             pe(t[x][o],mul(mul(f[x][j],f[to[i]][k]),d[j-1][k][o-1]));
    40         sz[x]+=sz[to[i]];rep(i,1,sz[x]) f[x][i]=t[x][i],t[x][i]=0;
    41     }
    42 }
    43 int main()
    44 {
    45     freopen("sort.in","r",stdin);
    46     freopen("sort.out","w",stdout);
    47     n=read(),m=read();char ch[2];rep(i,1,n) fa[i]=i;rep(i,1,m)
    48     {
    49         scanf("%d%s%d",&q[i].u,ch,&q[i].v);
    50         if(ch[0]=='=') fa[find(q[i].u)]=find(q[i].v),q[i].t=1;
    51     }
    52     rep(i,1,m) if(!q[i].t) add(find(q[i].u),find(q[i].v));
    53     rep(i,1,n) if(!vis[find(i)]&&!dfs(find(i))) {puts("0");return 0;}
    54     d[0][0][0]=1;rep(i,0,n) rep(j,0,n) rep(k,max(i,j),min(i+j,n)) if(i|j)
    55     {
    56         if(i) pe(d[i][j][k],d[i-1][j][k-1]);if(j) pe(d[i][j][k],d[i][j-1][k-1]);
    57         if(i*j) pe(d[i][j][k],d[i-1][j-1][k-1]);
    58     }
    59     rep(i,1,n) if(!ind[find(i)]) add(n+1,find(i));dp(n+1);int ans=0;
    60     rep(i,1,n+1) ans=pls(ans,f[n+1][i]);printf("%d
    ",ans);
    61 }
    View Code

    T2 mission

    题解链接

    考场的$dsu space on space tree$被卡掉了,写一波主席树合并

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define db double
     4 #define inf 2139092143
     5 #define MAXN 10100
     6 #define DMAXN 640100
     7 #define DMAXM 1280100
     8 #define MOD 998244353
     9 #define rep(i,s,t) for(register int i=(s),i##end=(t);i<=i##end;++i)
    10 #define dwn(i,s,t) for(register int i=(s),i##end=(t);i>=i##end;--i)
    11 #define ren for(int i=fst[x];i;i=nxt[i])
    12 #define pls(a,b) (a+b)%MOD
    13 #define mns(a,b) (a-b+MOD)%MOD
    14 #define mul(a,b) (1LL*a*b)%MOD
    15 #define ist(u,v,w) D::ins(u,v,w)
    16 using namespace std;
    17 inline int read()
    18 {
    19     int x=0,f=1;char ch=getchar();
    20     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    21     while(isdigit(ch)) {x=x*10+ch-'0',ch=getchar();}
    22     return x*f;
    23 }
    24 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,val[MAXN],fa[MAXN];
    25 int tot,ls[MAXN<<6],rs[MAXN<<6],ss,tt,rt[MAXN];
    26 namespace D
    27 {
    28     int S,T,fst[DMAXN],nxt[DMAXM<<1],to[DMAXM<<1],val[DMAXM<<1],cnt;
    29     int cur[DMAXN],vis[DMAXN],dis[DMAXN],q[DMAXN],l,r,tot;
    30     void mem(){memset(fst,0,sizeof(fst));cnt=1;}
    31     void add(int u,int v,int w){nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
    32     void ins(int u,int v,int w){add(u,v,w);add(v,u,0);}
    33     int bfs()
    34     {
    35         vis[T]=++tot,dis[T]=0,q[l=r=1]=T;int x;
    36         while(l<=r)
    37         {
    38             x=q[l++];cur[x]=fst[x];ren if(vis[to[i]]!=tot&&val[i^1])
    39                 vis[to[i]]=tot,dis[to[i]]=dis[x]+1,q[++r]=to[i];
    40         }
    41         return vis[S]==tot;
    42     }
    43     int dfs(int x,int a)
    44     {
    45         if(x==T||!a) return a;int flw=0,f;
    46         for(int& i=cur[x];i&&a;i=nxt[i])
    47             if(val[i]&&dis[to[i]]==dis[x]-1&&(f=dfs(to[i],min(a,val[i]))))
    48                 val[i]-=f,val[i^1]+=f,a-=f,flw+=f;
    49         return flw;
    50     }
    51     int solve(int s,int t,int ans=0)
    52     {
    53         S=s,T=t;int f;while(bfs()) ans+=dfs(S,inf);
    54         return ans;
    55     }
    56 };
    57 void add(int u,int v){nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    58 void mdf(int &k,int kk,int l,int r,int x)
    59 {
    60     k=++tot;if(l==r) {ist(k+n,x,inf);return ;}int mid=l+r>>1;
    61     if(val[x]<=mid) rs[k]=rs[kk],mdf(ls[k],ls[kk],l,mid,x);
    62     else ls[k]=ls[kk],mdf(rs[k],rs[kk],mid+1,r,x);
    63 }
    64 void query(int k,int l,int r,int a,int b,int x)
    65 {
    66     if(!k) return ;if(l==a&&r==b) {ist(tot+n,k+n,x);return ;}int mid=l+r>>1;
    67     if(b<=mid) query(ls[k],l,mid,a,b,x);else if(a>mid) query(rs[k],mid+1,r,a,b,x);
    68     else {query(ls[k],l,mid,a,mid,x);query(rs[k],mid+1,r,mid+1,b,x);}
    69 }
    70 int merge(int x,int y,int l,int r)
    71 {
    72     if(!(x*y)) return x|y;int z=++tot,mid=l+r>>1;
    73     if(l==r) {ist(z+n,x+n,inf);ist(z+n,y+n,inf);}
    74     ls[z]=merge(ls[x],ls[y],l,mid);rs[z]=merge(rs[x],rs[y],mid+1,r);return z;
    75 }
    76 void dfs(int x){mdf(rt[x],rt[x],1,n,x);ren dfs(to[i]),rt[x]=merge(rt[x],rt[to[i]],1,n);}
    77 int main()
    78 {
    79     freopen("mission.in","r",stdin);
    80     freopen("mission.out","w",stdout);
    81     n=read(),m=read();rep(i,2,n) fa[i]=read(),add(fa[i],i);rep(i,1,n) val[i]=read();
    82     D::mem();dfs(1);ss=0;int x,a,b,t,k;
    83     rep(i,1,tot) {if(ls[i]) ist(i+n,ls[i]+n,inf);if(rs[i]) ist(i+n,rs[i]+n,inf);}
    84     while(m--)
    85         {x=++tot,a=read(),b=read(),k=read(),t=read();ist(ss,x+n,t);query(rt[k],1,n,a,b,t);}
    86     tt=n+tot+1;rep(i,1,n) ist(i,tt,1);
    87     printf("%d
    ",D::solve(ss,tt));
    88 }
    View Code

    T3 path

    题目大意:

    一棵树,给出$m$条路径,求选出两个路径使其中一个被另一个完全包含的概率

    思路:

    考虑一个路径$asim b$被另一条路径所包含的情况,

    若$a==b$ 则另一个路径的两端点需要分别在子树内和子树外

    若$a$为$b$的祖先,则另一个路径的两端点需要在$b$的子树内,$a$在$asim b$上的儿子的子树外

    若$a,b$互不为祖先,则分别在$a,b$的子树内

    将两个值同时在两个区间里的限制条件转换成一个二维点在矩形里的条件

    然后扫描线树状数组二维数点查询每个点在哪几个矩形里即可

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define db double
     4 #define inf 2139092143
     5 #define MAXN 530100
     6 #define MOD 998244353
     7 #define rep(i,s,t) for(register int i=(s),i##end=(t);i<=i##end;++i)
     8 #define dwn(i,s,t) for(register int i=(s),i##end=(t);i>=i##end;--i)
     9 #define ren for(int i=fst[x];i;i=nxt[i])
    10 #define pls(a,b) (a+b)%MOD
    11 #define mns(a,b) (a-b+MOD)%MOD
    12 #define mul(a,b) (1LL*a*b)%MOD
    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 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,dep[MAXN];
    22 int f[21][MAXN],in[MAXN],ou[MAXN],tot,c[MAXN];ll ans;
    23 void mdf(int x,int val) {for(;x<=n;x+=x&-x) c[x]+=val;}
    24 int query(int x,int res=0) {for(;x;x-=x&-x) res+=c[x];return res;}
    25 struct pnt{int x,y;}p[MAXN];struct seg{int x,l,r,w;}g[MAXN<<2];
    26 bool operator < (const pnt &a,const pnt &b) {return a.x<b.x;}
    27 bool operator == (const pnt &a,const pnt &b) {return a.x==b.x&&a.y==b.y;}
    28 bool operator < (const seg &a,const seg &b) {return a.x<b.x;}
    29 void add(int u,int v){nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    30 void dfs(int x)
    31 {
    32     in[x]=++tot;rep(j,1,20) f[j][x]=f[j-1][f[j-1][x]];
    33     ren if(to[i]^f[0][x]) f[0][to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);ou[x]=tot;
    34 }
    35 int anc(int x,int k){rep(i,0,20) if((1<<i)&k) x=f[i][x];return x;}
    36 void ivt(int x,int y,int l,int r)
    37 {
    38     if(l>r||x>y) return ;if(x>l) swap(x,l),swap(y,r);
    39     g[++tot]=(seg){x,l,r,1},g[++tot]=(seg){y+1,l,r,-1};
    40 }
    41 ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
    42 int main()
    43 {
    44     freopen("path.in","r",stdin);
    45     freopen("path.out","w",stdout);
    46     n=read(),m=read();int a,b;rep(i,2,n) a=read(),b=read(),add(a,b),add(b,a);
    47     f[0][1]=1;dfs(1);tot=0;rep(i,1,m)
    48     {
    49         a=read(),b=read();p[i]=(pnt){min(in[a],in[b]),max(in[a],in[b])};
    50         if(dep[b]>dep[a]) swap(a,b);
    51         if(a==b) ivt(in[a],ou[a],1,in[a]),ivt(in[a],ou[a],ou[a]+1,n);
    52         if(in[b]<=in[a]&&in[a]<=ou[b])
    53         {
    54             b=anc(a,dep[a]-dep[b]-1);
    55             ivt(in[a],ou[a],1,in[b]-1),ivt(in[a],ou[a],ou[b]+1,n);
    56         }
    57         else ivt(in[a],ou[a],in[b],ou[b]);
    58     }
    59     sort(p+1,p+m+1);sort(g+1,g+tot+1);int pos=1;
    60     rep(i,1,m)
    61     {
    62         for(;pos<=tot&&g[pos].x<=p[i].x;pos++) mdf(g[pos].l,g[pos].w),mdf(g[pos].r+1,-g[pos].w);
    63         ans+=query(p[i].y);
    64     }
    65     pos=1;rep(i,1,m) {for(;pos<=m&&p[i]==p[pos];pos++);ans-=1LL*(pos-i)*(pos-i-1)>>1;i=pos-1;}
    66     ans-=m;printf("%.6lf",2.0*ans/m/(m-1));
    67 }
    View Code
  • 相关阅读:
    八张图读懂未来“互联网+”的六大趋势
    跑一段代码遍历所有汉字
    PHP业务逻辑层和数据访问层设计
    漫谈社区PHP 业务开发
    以Apache服务器、php语言为例 详解动态网站的访问过程
    sublime text
    《产品经理的20堂必修课》
    检测文件是否有bom头
    利用开源框架Volley来下载文本和图片。
    往SD卡中写文件的方法。
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10583184.html
Copyright © 2011-2022 走看看