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

    T1 

    题目大意:

    一棵树有正边权,$Q$次询问,询问$x$与编号在$[l,r]$之间的点的最小距离

    思路:

    建立点分树,由于在每个分治重心内任意两个点的lca可以看做重心

    我们可以预处理出一个点到他点分树上所有的祖先的距离,每个点最多处理$log$个距离

    对每个重心维护动态开点线段树,把每个点暴力加入到它点分树上祖先的线段树

    查询的时候暴力查询所有祖先的线段树即可

     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 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 21390621430000000LL
    14 #define MAXN 100100
    15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    17 #define ren for(register int i=fst[x];i;i=nxt[i])
    18 #define pb(i,x) vec[i].push_back(x)
    19 #define pls(a,b) (a+b)%MOD
    20 #define mns(a,b) (a-b+MOD)%MOD
    21 #define mul(a,b) (1LL*(a)*(b))%MOD
    22 using namespace std;
    23 inline int read()
    24 {
    25     int x=0,f=1;char ch=getchar();
    26     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    27     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 int n,nxt[MAXN<<1],fst[MAXN],to[MAXN<<1],cnt,val[MAXN<<1];
    31 int sz[MAXN],mx[MAXN],Mx,Sum,Rt,vis[MAXN],dep[MAXN],fa[MAXN];
    32 ll dis[MAXN][20];
    33 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
    34 void getrt(int x,int pa)
    35 {
    36     sz[x]=1,mx[x]=0;ren if(to[i]^pa&&!vis[to[i]])
    37         {getrt(to[i],x);sz[x]+=sz[to[i]];mx[x]=max(mx[x],sz[to[i]]);}
    38     mx[x]=max(mx[x],Sum-sz[x]);if(mx[x]<Mx) Mx=mx[x],Rt=x;
    39 }
    40 void Get(int x,int pa,int d){ren if(!vis[to[i]]&&to[i]^pa) dis[to[i]][d]=dis[x][d]+val[i],Get(to[i],x,d);}
    41 void div(int x)
    42 {
    43     vis[x]=1;dis[x][dep[x]]=0;Get(x,0,dep[x]);
    44     ren if(!vis[to[i]]) 
    45         {Sum=sz[to[i]],Mx=n+2;getrt(to[i],0);dep[Rt]=dep[x]+1,fa[Rt]=x;div(Rt);}
    46 }
    47 ll mn[MAXN<<7];int ls[MAXN<<7],rs[MAXN<<7],rt[MAXN],tot;
    48 void mdf(int &k,int l,int r,int x,ll w)
    49 {
    50     if(!k) k=++tot,mn[k]=inf;mn[k]=min(mn[k],w);if(l==r) return ;int mid=l+r>>1;
    51     if(x<=mid) mdf(ls[k],l,mid,x,w);else mdf(rs[k],mid+1,r,x,w);
    52 }
    53 ll query(int k,int l,int r,int a,int b)
    54 {
    55     if(!k) return inf;if(l==a&&r==b) return mn[k];int mid=l+r>>1;
    56     if(b<=mid) return query(ls[k],l,mid,a,b);
    57     else if(a>mid) return query(rs[k],mid+1,r,a,b);
    58     else return min(query(ls[k],l,mid,a,mid),query(rs[k],mid+1,r,mid+1,b));
    59 }
    60 void Mdf(int x){for(int anc=x;dep[anc];anc=fa[anc]) mdf(rt[anc],1,n,x,dis[x][dep[anc]]);}
    61 ll Query(int x,int l,int r,ll res=inf)
    62 {
    63     for(int anc=x;dep[anc];anc=fa[anc]){res=min(res,dis[x][dep[anc]]+query(rt[anc],1,n,l,r));}
    64     return res;
    65 }
    66 int main()
    67 {
    68     n=read();int a,b,c;rep(i,2,n) a=read(),b=read(),c=read(),add(a,b,c),add(b,a,c);
    69     Mx=n+2,Sum=n;getrt(1,0);dep[Rt]=1;div(Rt);rep(i,1,n) Mdf(i);
    70     int T=read();while(T--) {a=read(),b=read(),c=read();printf("%lld
    ",Query(c,a,b));}
    71 }
    View Code

    T2 

    题目大意:

    把$n$个本质不同的东西分给$m$个本质相同的人,定义每种方案的权值为所有人拿到东西的数目成绩

    求所有方案的权值和

    思路:

    对于每个方案的权值,可以看做给方案中对每个人都选一朵花的方案数

    则我们可以先枚举出选出的这$m$朵花,即$C_n^m$ 剩下的花随便放即$m^{n-m}$,总方案数为贡献

     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 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 100100
    15 #define MOD 998244353
    16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    18 #define ren for(register int i=fst[x];i;i=nxt[i])
    19 #define pb(i,x) vec[i].push_back(x)
    20 #define pls(a,b) (a+b)%MOD
    21 #define mns(a,b) (a-b+MOD)%MOD
    22 #define mul(a,b) (1LL*(a)*(b))%MOD
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    28     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,m,pw[MAXN],ipw[MAXN];
    32 int q_pow(int bas,int t,int res=1)
    33 {
    34     for(;t;t>>=1,bas=mul(bas,bas))
    35         if(t&1) res=mul(res,bas);return res;
    36 }
    37 int C(int n,int m) {return mul(pw[n],mul(ipw[m],ipw[n-m]));}
    38 int main()
    39 {
    40     n=read(),m=read();pw[0]=1;rep(i,1,n) pw[i]=mul(pw[i-1],i),ipw[i]=q_pow(pw[i],MOD-2);
    41     printf("%d
    ",mul(C(n,m),q_pow(m,n-m)));
    42 }
    View Code

    T3

    题目大意:

    求树上选出$m$个点的点独立集的所有方案的权值和,一个方案的权值定义为选出的点的权值的乘积

    思路:

    设$f_{x,0/1}$表示选不选$x$这个点的答案

    考虑合并一个新的子树进来合并,$f_{i+j,0}=t_{i,0}*f{j,0}$ 是一个卷积的形式

    则我们可以用$ntt$来合并,但显然复杂度是不满足的

    考虑重链剖分,先把重链上每个点的其他儿子的贡献算出来,得到一个$g_{x,0/1}$数组

    为了快速合并重链上的信息,我们还需要记录选头不选尾,选尾不选头的情况。这样就可以用分治来优化了

    这样一路合并上去就可以得到答案了

    (指针可真是个弟弟,谜之分配内存

      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 ll long long
     11 #define db double
     12 #define inf 2139092143
     13 #define MAXN 160100
     14 #define MOD 998244353
     15 #define rep(i,s,t) for(register int i=(s),i##end=(t);i<=i##end;++i)
     16 #define dwn(i,s,t) for(register int i=(s),i##end=(t);i>=i##end;--i)
     17 #define ren(x) for(int i=fst[x];i;i=nxt[i])
     18 #define pls(a,b) (a%MOD+b%MOD)%MOD
     19 #define mns(a,b) ((a%MOD-b%MOD)%MOD+MOD)%MOD
     20 #define mul(a,b) (1LL*(a%MOD)*(b%MOD))%MOD
     21 #define inv(x) q_pow(x,MOD-2)
     22 using namespace std;
     23 inline int read()
     24 {
     25     int x=0,f=1;char ch=getchar();
     26     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
     27     while(isdigit(ch)) {x=x*10+ch-'0',ch=getchar();}
     28     return x*f;
     29 }
     30 int w[MAXN],n,m,nxt[MAXN<<1],fst[MAXN],to[MAXN<<1],cnt;
     31 int sz[MAXN],hsh[MAXN],hvs[MAXN],fa[MAXN],tot,t[MAXN],tt[MAXN];
     32 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
     33 int A[MAXN<<2],B[MAXN<<2],pw[30],ipw[30],rev[MAXN<<2],l2[MAXN<<2],tmp[MAXN<<8],*id=tmp;
     34 int q_pow(int bas,int t,int res=1)
     35 {
     36     for(;t;t>>=1,bas=mul(bas,bas))
     37         if(t&1) res=mul(res,bas);return res;
     38 }
     39 void ntt(int *a,int n,int f)
     40 {
     41     rep(i,0,n-1) if(i<rev[i]) swap(a[i],a[rev[i]]);
     42     for(int i=1;i<n;i<<=1)
     43     {
     44         int wn=f>0?pw[l2[i]+1]:ipw[l2[i]+1];
     45         for(int j=0;j<n;j+=i<<1)
     46         {
     47             int w=1,x,y;
     48             for(int k=0;k<i;++k,w=mul(w,wn))
     49                 x=a[j+k],y=mul(a[j+k+i],w),a[j+k]=pls(x,y),a[j+k+i]=mns(x,y);
     50         }
     51     }
     52     if(f>0) return ;int nv=inv(n);rep(i,0,n-1) a[i]=mul(a[i],nv);
     53 }
     54 struct poly
     55 {
     56     int *a,len;void mem(int x) {len=x,a=id,id+=len;}
     57     poly operator * (const poly &b) const
     58     {
     59         poly res;res.mem(len+b.len-1);int t=l2[res.len]+1,lmt=1<<t;
     60         if(res.len<=100)
     61         {
     62             rep(i,0,len-1) rep(j,0,b.len-1) if(i+j<res.len)
     63                 res.a[i+j]=pls(mul(a[i],b.a[j]),res.a[i+j]);return res;
     64         }
     65         rep(i,0,lmt-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<t-1),A[i]=B[i]=0;
     66         rep(i,0,len-1) A[i]=a[i];rep(i,0,b.len-1) B[i]=b.a[i];
     67         ntt(A,lmt,1);ntt(B,lmt,1);
     68         rep(i,0,lmt-1) A[i]=mul(A[i],B[i]);ntt(A,lmt,-1);
     69         rep(i,0,res.len-1) res.a[i]=A[i];return res;
     70     }
     71     poly operator + (const poly &b) const
     72     {
     73         poly res;res.mem(max(len,b.len));
     74         rep(i,0,res.len-1) res.a[i]=pls((i<len?a[i]:0),(i<b.len?b.a[i]:0));return res;
     75     }
     76 }f[MAXN][2],g[MAXN][2],One,Zero;
     77 poly solve(int l,int r,int D)
     78 {
     79     if(l==r) return f[t[l]][D];int mid=l+r>>1;
     80     return solve(l,mid,D)*solve(mid+1,r,D);
     81 }
     82 struct mat{poly a[2][2];void mem() {a[0][0]=a[0][1]=a[1][1]=a[1][0]=Zero;}};
     83 mat merge(const mat &x,const mat &y)
     84 {
     85     mat res;res.a[1][1]=x.a[1][0]*(y.a[0][1]+y.a[1][1])+x.a[1][1]*y.a[0][1];
     86     res.a[1][0]=x.a[1][0]*(y.a[0][0]+y.a[1][0])+x.a[1][1]*y.a[0][0];
     87     res.a[0][1]=x.a[0][0]*(y.a[0][1]+y.a[1][1])+x.a[0][1]*y.a[0][1];
     88     res.a[0][0]=x.a[0][0]*(y.a[0][0]+y.a[1][0])+x.a[0][1]*y.a[0][0];return res;
     89 }
     90 mat solve(int l,int r)
     91 {
     92     if(l==r) {mat res;res.mem();res.a[0][0]=g[tt[l]][0],res.a[1][1]=g[tt[l]][1];return res;}
     93     int mid=l+r>>1;return merge(solve(l,mid),solve(mid+1,r));
     94 }
     95 void dfs(int x,int pa)
     96 {
     97     fa[x]=pa,hsh[++tot]=x,sz[x]=1;
     98     ren(x) if(to[i]^pa) dfs(to[i],x),sz[x]+=sz[to[i]],hvs[x]=sz[to[i]]>sz[hvs[x]]?to[i]:hvs[x];
     99 }
    100 void work(int x)
    101 {
    102     int l1=0,l2;poly it;mat res;
    103     for(int y=x;y;y=hvs[y])
    104     {
    105         tt[++l1]=y,l2=0;ren(y) if(to[i]^fa[y]&&to[i]^hvs[y]) t[++l2]=to[i];
    106         it.mem(2);it.a[0]=0;it.a[1]=w[y];if(!l2) g[y][0]=One,g[y][1]=it;
    107         else g[y][0]=solve(1,l2,1),g[y][1]=solve(1,l2,0)*it;
    108     }
    109     res=solve(1,l1);f[x][0]=res.a[0][0]+res.a[0][1];
    110     f[x][1]=f[x][0]+res.a[1][0]+res.a[1][1];
    111 }
    112 int main()
    113 {
    114     n=read(),m=read();int a,b;rep(i,1,n) w[i]=read();One.mem(1);One.a[0]=1;
    115     rep(i,2,n) a=read(),b=read(),add(a,b),add(b,a);Zero.mem(1);
    116     rep(i,2,n<<2) 
    117     {
    118         l2[i]=l2[i>>1]+1;
    119         if(!pw[l2[i]]) pw[l2[i]]=q_pow(3,(MOD-1)/i),ipw[l2[i]]=inv(pw[l2[i]]);
    120     }
    121     dfs(1,0);dwn(i,n,1) {a=hsh[i];if(hvs[fa[a]]^a) work(a);}
    122     printf("%d
    ",f[1][1].len>=m+1?f[1][1].a[m]:0);
    123 }
    View Code
  • 相关阅读:
    使用canvas实现擦玻璃效果
    安装jdk For Windows
    墙裂推荐4款js网页烟花特效
    再次推荐一款逼真的HTML5下雪效果
    HTML5播放暂停音乐
    周末web前端练习
    Javascript贪食蛇小游戏
    jquery实现更多内容效果
    jQuery省市区三级联动插件
    Web前端测试题
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10609735.html
Copyright © 2011-2022 走看看