• 3.15 模拟赛


    T1 1e5只龙的故事

    题目大意:

    一棵树 q次询问 每次询问一条路径上的第$k$小的点的权值(不去重),然后把整个路径上所有点的权值都改成这个值

    思路:

    好暴力啊

    使用树剖线段树暴力维护权值一样的区间 查询的时候开个数组记录所有满足条件的区间 排序后直接查即可

     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 180100
    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],tag[MAXN<<2];
    31 int sz[MAXN],dep[MAXN],fa[MAXN],hvs[MAXN],bl[MAXN],in[MAXN],tot;
    32 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    33 void dfs(int x,int pa)
    34 {
    35     sz[x]=1,fa[x]=pa;ren if(to[i]^pa) 
    36         {dep[to[i]]=dep[x]+1;dfs(to[i],x);sz[x]+=sz[to[i]],hvs[x]=sz[to[i]]>sz[hvs[x]]?to[i]:hvs[x];}
    37 }
    38 void Dfs(int x,int anc)
    39 {
    40     bl[x]=anc,in[x]=++tot;if(!hvs[x]) return ;Dfs(hvs[x],anc);
    41     ren if(to[i]^fa[x]&&to[i]^hvs[x]) Dfs(to[i],to[i]);
    42 }
    43 struct ask{int x,v;}res[MAXN];int top;
    44 void pshd(int k) {if(tag[k]) tag[k<<1]=tag[k<<1|1]=tag[k],tag[k]=0;}
    45 void mdf(int k,int l,int r,int a,int b,int x)
    46 {
    47     if(l==a&&r==b) {tag[k]=x;return ;}int mid=l+r>>1;pshd(k);
    48     if(b<=mid) mdf(k<<1,l,mid,a,b,x);else if(a>mid) mdf(k<<1|1,mid+1,r,a,b,x);
    49     else {mdf(k<<1,l,mid,a,mid,x);mdf(k<<1|1,mid+1,r,mid+1,b,x);}
    50 }
    51 void query(int k,int l,int r,int a,int b)
    52 {
    53     if(l==a&&r==b&&tag[k]) {res[++top]=(ask){tag[k],r-l+1};return ;}int mid=l+r>>1;pshd(k);
    54     if(b<=mid) query(k<<1,l,mid,a,b);else if(a>mid) query(k<<1|1,mid+1,r,a,b);
    55     else {query(k<<1,l,mid,a,mid);query(k<<1|1,mid+1,r,mid+1,b);}
    56 }
    57 bool cmp(ask a,ask b){return a.x<b.x;}
    58 int Query(int a,int b,int k)
    59 {
    60     for(top=0;bl[a]!=bl[b];a=fa[bl[a]])
    61         {if(dep[bl[a]]<dep[bl[b]]) swap(a,b);query(1,1,n,in[bl[a]],in[a]);}
    62     if(in[a]>in[b]) swap(a,b);query(1,1,n,in[a],in[b]);
    63     sort(res+1,res+top+1,cmp);int sum=0;rep(i,1,top) {sum+=res[i].v;if(sum>=k) return res[i].x;}
    64 }
    65 void work(int a,int b,int k)
    66 {
    67     for(;bl[a]!=bl[b];a=fa[bl[a]])
    68         {if(dep[bl[a]]<dep[bl[b]]) swap(a,b);mdf(1,1,n,in[bl[a]],in[a],k);}
    69     if(in[a]>in[b]) swap(a,b);mdf(1,1,n,in[a],in[b],k);
    70 }
    71 int main()
    72 {
    73     n=read();int a,b,x=read(),y=read(),MOD=read();
    74     rep(i,1,n) val[i]=read();rep(i,2,n) a=read(),b=read(),add(a,b),add(b,a);
    75     int q=read(),k;dfs(1,0);Dfs(1,1);rep(i,1,n) mdf(1,1,n,in[i],in[i],val[i]);
    76     while(q--)
    77         {a=read(),b=read(),k=read();k=Query(a,b,k);printf("%d
    ",k);work(a,b,pls(mul(k,x),y)+1);}
    78 }
    View Code

    T2 小R的箱子

    题目大意:

    每个箱子有长$x$和宽$y$,只有满足$a.x<=b.x$且$a.y<=b.y$才能把$a$装进$b$内(不能交换x y

    且每个箱子里只能装一个,但是可以嵌套。

    思路:

    每个箱子向可以装它的箱子连边,费用为起点箱子的面积

    把每个点拆成两个点,分别与$S$,$T$连边来限制流量,跑一个最大费用流

    用总费用去减即可

    这样就需要去重,所有相等的看做一个,其余的直接装进去(否则两个相等的会互相装

    (原来一直以来我的费用流都是假的,自闭了

     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 510
    15 #define MAXM 40100
    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,x[MAXN],y[MAXN],S,T,ban[MAXN];
    32 struct ZKW
    33 {
    34     int fst[MAXN],to[MAXM<<1],nxt[MAXM<<1],val[MAXM<<1],cos[MAXM<<1],cnt;
    35     int dis[MAXN],vis[MAXN],res;
    36     ZKW() {res=0,cnt=1;memset(fst,0,sizeof(fst));}
    37     void add(int u,int v,int w,int c) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w,cos[cnt]=c;}
    38     void ins(int u,int v,int w,int c) {add(u,v,w,c);add(v,u,0,-c);}
    39     int spfa()
    40     {
    41         memset(dis,127,sizeof(dis));
    42         queue<int> q;
    43         dis[T]=0,vis[T]=1;q.push(T);
    44         while(!q.empty())
    45         {
    46             int x=q.front();q.pop();vis[x]=0;
    47             for(int i=fst[x];i;i=nxt[i])
    48                 if(val[i^1]&&dis[to[i]]>dis[x]-cos[i])
    49                 {
    50                     dis[to[i]]=dis[x]-cos[i];
    51                     if(!vis[to[i]]) {q.push(to[i]);vis[to[i]]=1;}
    52                 }
    53         }
    54         return dis[S]!=inf;
    55     }
    56     int dfs(int x,int a)
    57     {
    58         if(x==T||!a) {res+=dis[S]*a;return a;}
    59         if(vis[x])return 0;
    60         vis[x]=1;
    61         int res=0,f;
    62         for(int i=fst[x];i&&a;i=nxt[i])
    63             if(val[i]&&dis[to[i]]==dis[x]-cos[i]&&(f=dfs(to[i],min(a,val[i]))))
    64                 res+=f,val[i]-=f,val[i^1]+=f,a-=f;
    65         return res;
    66     }
    67     void solve(int flw=0) 
    68     {
    69         int f;while(spfa()) 
    70             do{memset(vis,0,sizeof(vis));f=dfs(S,inf),flw+=f;}while(f);
    71     }
    72 }Z;
    73 int main()
    74 {
    75     n=read();rep(i,1,n) x[i]=read(),y[i]=read();S=(n<<1)+10,T=S+1;int sum=0;
    76     rep(i,1,n) rep(j,i+1,n) if(x[i]==x[j]&&y[i]==y[j]) ban[max(j,i)]=1;
    77     rep(i,1,n) rep(j,1,n) if(i!=j&&x[i]<=x[j]&&y[i]<=y[j]&&ban[i]==0&&ban[j]==0) Z.ins(i,j+n,1,-x[i]*y[i]);
    78     rep(i,1,n) if(!ban[i]) Z.ins(S,i,1,0),Z.ins(i+n,T,1,0),sum+=x[i]*y[i];
    79     Z.solve();
    80     printf("%d
    ",sum+Z.res);
    81 }
    View Code

    T3 绯红之王

    题目大意:

    已知数列$a$,求$sumlimits_{i=1}^n {a_i}^k$

    思路:

    很久以前讲过的题,调了一年才搞出来

    首先设$f_k=sumlimits_{i=1}^n {a_i}^k$ , $g_k$表示对于所有$C_n^k$种选择的方法,$g_k=$所有方法内各个数相乘的和

    例如数列中有四个数$a,b,c,d$ 则

    $g_0=1$

    $g_1=a+b+c+d$

    $g_2=ab+ac+ad+bc+bd+cd$

    $g_3=abc+abd+acd+bcd,g_4=abcd$

    我们可以发现

    $f_2=f_1 * g_1 - 2g_2$

    $f_3=f_2 * g_1 - f_1* g_2 + 3g_3$

    $f_4=f_3*g_1-f_2*g_2+f_1*g_3-4g_4$

    发现下标为偶数的$g$都变成了其相反数,而且这是一个$f_0$在变化的分治$NTT$形式

    那么我们将$f_0$设为0,在$cdq$到$l==r$时,再加上这个$n*g_n$贡献

    现在考虑如何计算$g$数组,因为$g_i$是齐次轮换对称式 可以通过计算两部分再合并

    例如$h_0=1,h_1=a+b+c,h_2=ab+ac+bc,h_3=abc$

    $t_0=1,t_1=d+e+f,t_2=de+df+ed,t_3=def$

    则$g_0=h_0*t_0=1$

    $g_1=h_0*t_1+h_1*t_0$

    $g_2=h_0*t_2+h_1*t_1+h_2*t_0$

    $......$

    这样可以维护一个类似线段树的结构来计算$g$,即一开始每个点有一个自己的多项式$1,a_i$

    然后一层一层往上合并,计算出$g$后再用分治$NTT$来计算$f$

     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 800100
    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) (1LL*a%MOD+b%MOD+MOD)%MOD
    21 #define mns(a,b) (1LL*a%MOD-b%MOD+MOD)%MOD
    22 #define mul(a,b) ((ll)(1LL*(a))%MOD*(b)%MOD)%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,rev[MAXN],l2[MAXN],pw[MAXN],A[MAXN],B[MAXN],aa[MAXN];
    32 int g[MAXN],f[MAXN];
    33 vector<int> vec[MAXN];
    34 int q_pow(int bas,int t,int res=1)
    35 {
    36     for(;t;bas=mul(bas,bas),t>>=1)
    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=pw[i<<1];if(f==-1) wn=q_pow(wn,MOD-2);
    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[k+j],y=mul(a[i+j+k],w),a[j+k]=pls(x,y),a[i+j+k]=mns(x,y);
    50         }
    51     }
    52     if(f==1) return ;int nv=q_pow(n,MOD-2);
    53     rep(i,0,n-1) a[i]=mul(a[i],nv);
    54 }
    55 void solve(int *a,int *b,int lmt)
    56 {
    57     ntt(a,lmt,1);ntt(b,lmt,1);rep(i,0,lmt-1) a[i]=mul(a[i],b[i]);
    58     ntt(a,lmt,-1);
    59 }
    60 void Div(int l,int r,ll lmt=0)
    61 {
    62     if(l==r) return ;int mid=(l+r)>>1,lg;
    63     Div(l,mid);Div(mid+1,r);lg=l2[r-l+1]+1,lmt=1<<lg;
    64     rep(i,0,lmt-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)),A[i]=B[i]=0;
    65     rep(i,0,vec[l].size()-1) A[i]=vec[l][i];
    66     rep(i,0,vec[mid+1].size()-1) B[i]=vec[mid+1][i];
    67     solve(A,B,lmt);
    68     vec[l].clear();vec[mid+1].clear();
    69     rep(i,0,lmt-1) vec[l].push_back(A[i]);
    70 }
    71 void cdq(int l,int r)
    72 {
    73     if(l==r) {f[l]=pls(f[l],mul(g[l],l));return ;}
    74     int mid=l+r>>1,lmt=r-l+1;cdq(l,mid);
    75     int t=l2[lmt]+1;lmt=1<<t;
    76     rep(i,0,lmt-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(t-1)),A[i]=B[i]=0;
    77     rep(i,l,mid) A[i-l]=f[i];rep(i,1,r-l) B[i-1]=g[i];
    78     solve(A,B,lmt);rep(i,mid+1,r) f[i]=pls(f[i],A[i-l-1]);
    79     cdq(mid+1,r);
    80 }
    81 int main()
    82 {
    83     n=read();rep(i,1,n) aa[i]=read();rep(i,2,n<<1) l2[i]=l2[i>>1]+1;
    84     rep(i,1,n<<1) pw[i]=q_pow(3,(MOD-1)/i);
    85     rep(i,1,n) vec[i].push_back(1),vec[i].push_back(aa[i]);
    86     Div(1,n);rep(i,0,n) g[i]=vec[1][i];
    87     rep(i,0,n) if(!(i&1)) g[i]=-g[i];
    88     cdq(0,n);rep(i,1,n) printf("%d
    ",f[i]);
    89 }
    View Code
  • 相关阅读:
    字符串、列表(操作)
    数据类型
    第二周 第四部分
    第二周 第三部分
    第二周第二部分
    特征缩放和标准化 设置学习率大小 正则方程
    梯度下降 coursera.org
    监督学习和无监督学习
    手写数字问题
    pytorch基础
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10539856.html
Copyright © 2020-2023  润新知