首页 > 其他分享 >冲刺国赛模拟 7

冲刺国赛模拟 7

时间:2023-05-23 15:46:34浏览次数:43  
标签:5010 frac int dp 冲刺 国赛 510 include 模拟

迷惑,开三道题发现 T3 见过原题没做。然后在 kai586123 老师课件里边找到了这题题号。震撼,震撼。

不知道 NJU 营春测卡多少分。

第一题

正解是把询问对列分治,然后考虑跨过中间列的询问。

暴力 \(O(\dfrac{n^4}w+q)\) 的方法是显然的,可以获得 \(50-100\) 分不等,略微卡常后通过。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#include <bitset>
using namespace std;
int n,m,Q,num,id[510][510];
char s[510][510];
bool ans[1000010];
bitset<510>f[510][510];
struct node{
    pair<int,int>u,v;
    int id;
};
vector<node>q[510];
void tuopu(int id){
    for(int i=id;i<=n;i++)for(int j=1;j<=m;j++)f[i][j].reset();
    for(int j=1;j<=m;j++)f[id][j][j]=1;
    for(int i=id;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(s[i][j]=='1')continue;
            if(s[i+1][j]=='0')f[i+1][j]|=f[i][j];
            if(s[i][j+1]=='0')f[i][j+1]|=f[i][j];
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&Q);
    for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
    for(int i=1;i<=Q;i++){
        int x1,x2,y1,y2;scanf("%d%d%d%d",&x1,&x2,&y1,&y2);
        node ret={make_pair(x1,y1),make_pair(x2,y2),i};
        q[x1].push_back(ret);
    }
    for(int i=1;i<=n;i++){
        if(q[i].empty())continue;
        tuopu(i);
        for(node p:q[i]){
            if(f[p.v.first][p.v.second][p.u.second])ans[p.id]=true;
        }
    }
    for(int i=1;i<=Q;i++)puts(ans[i]?"Yes":"No");
    return 0;
}

第二题

题面说的对。

考虑在中间合并两边,那两边一定是一堆指向中间的链,且链数相差不超过 \(1\)。于是对前缀做一遍 dp,对后缀再做一遍,乘两个阶乘合并,如果链数相等还要乘 \(2\)。

以从前往后 dp 为例。设 \(dp_{i,j}\) 为到 \(i\) 有 \(j\) 条链的方案数,转移考虑这一位是什么:

  1. >:两种情况:新建一条链 \(dp_{i-1,j-1}\),并在另一条链的末尾 \(j\times dp_{i-1,j}\)。
  2. <:两种情况:作为一条链开头 \(j\times dp_{i-1,j}\),合并两条链 \(j(j-1)\times dp_{i-1,j+1}\)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod=1000000007;
int n,jc[5010],f[5010][5010],g[5010][5010];
char s[5010];
int C(int n){
    return (1ll*n*(n-1)>>1)%mod;
}
int main(){
    scanf("%s",s+1);n=strlen(s+1);jc[0]=1;
    for(int i=1;i<=n;i++)jc[i]=1ll*jc[i-1]*i%mod;
    f[0][0]=1;
    for(int i=1;i<=n;i++){
        if(s[i]=='>'){
            for(int j=1;j<=n;j++){
                f[i][j]=(f[i][j]+f[i-1][j-1])%mod;
                f[i][j]=(f[i][j]+1ll*j*f[i-1][j])%mod;
            }
        }
        else{
            for(int j=1;j<=n;j++){
                f[i][j]=(f[i][j]+1ll*j*f[i-1][j])%mod;
                f[i][j]=(f[i][j]+2ll*C(j+1)*f[i-1][j+1])%mod;
            }
        }
    }
    g[n+1][0]=1;
    for(int i=n;i>=1;i--){
        if(s[i]=='<'){
            for(int j=1;j<=n;j++){
                g[i][j]=(g[i][j]+g[i+1][j-1])%mod;
                g[i][j]=(g[i][j]+1ll*j*g[i+1][j])%mod;
            }
        }
        else{
            for(int j=1;j<=n;j++){
                g[i][j]=(g[i][j]+1ll*j*g[i+1][j])%mod;
                g[i][j]=(g[i][j]+2ll*C(j+1)*g[i+1][j+1])%mod;
            }
        }
    }
    for(int i=1;i<=n;i++){
        int ans=0;
        for(int j=0;j<=n;j++){
            int ret=1ll*jc[j]*jc[j+1]%mod;
            int val=(1ll*f[i-1][j]*g[i+1][j+1]+1ll*f[i-1][j+1]*g[i+1][j])%mod;
            ans=(ans+1ll*ret*val)%mod;
            ans=(ans+2ll*jc[j]*jc[j]%mod*f[i-1][j]%mod*g[i+1][j])%mod;
        }
        printf("%d ",ans);
    }
    puts("");
    return 0;
}

第三题

原题 CF923E,这好像是场 ACM,赛时过了 300 队。

首先每次操作是把 \(f_i\) 变成 \(\sum_{j=i}^n\frac{f_j}{j+1}\)。然后写成生成函数的形式就是

\[\begin{aligned} &G(x)=\sum_{i=0}^nx^i\sum_{j=i}^n\frac{f_j}{j+1}\\ =&\sum_{j=0}^n\frac{f_j}{j+1}\sum_{i=0}^jx^i\\ =&\frac 1{1-x}\sum_{j=0}^n\frac{f_j}{j+1}(1-x^{j+1})\\ =&\frac 1{1-x}\int_x^1F(z)\text dz \end{aligned} \]

这个积分的上界是个 \(1\) 很 \(2\sqrt 2\),给他怼成 \(0\)。设个 \(P(x)=F(x+1)\),就有了

\[\begin{aligned} G(x)&=\frac 1{1-x}\int_x^1F(z)\text dz\\ &=\frac 1{1-x}\int_{x-1}^0P(z)\text dz\\ &=\frac 1{x-1}\int_0^{x-1}P(z)\text dz \end{aligned} \]

这时候思路大概很明显了。设 \(Q(x)=G(x+1)\):

\[Q(x)=\frac 1x\int P(z)\text dz \]

那显然 \([x^i]Q(x)=\frac 1{i+1}[x^i]P(x)\)。于是就是两次多项式平移。

存在手解矩阵对角化方法,但我不会线性代数。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
const int mod=998244353;
#define add(x,y) (x+y>=mod?x+y-mod:x+y)
#define sub(x,y) (x-y<0?x-y+mod:x-y)
typedef vector<int> poly;
int wl;
void get(int n){
    wl=1;
    while(wl<n)wl<<=1;
}
int qpow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=1ll*ans*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return ans;
}
int jc[300010],inv[300010],Inv[300010],w[300010];
void init(int n){
    int t=1;
    while((1<<t)<n)t++;
    t=min(t-1,21);
    w[0]=1;w[1<<t]=qpow(31,1<<21-t);
    for(int i=t;i>=1;i--)w[1<<i-1]=1ll*w[1<<i]*w[1<<i]%mod;
    for(int i=1;i<(1<<t);i++)w[i]=1ll*w[i&i-1]*w[i&-i]%mod;
    jc[0]=Inv[0]=inv[1]=1;
    for(int i=2;i<=n;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    for(int i=1;i<=n;i++)jc[i]=1ll*jc[i-1]*i%mod,Inv[i]=1ll*Inv[i-1]*inv[i]%mod;
}
inline void DIF(poly &a){
    int n=a.size();
    for(int mid=n>>1;mid>=1;mid>>=1){
        for(int i=0,k=0;i<n;i+=mid<<1,k++){
            for(int j=0;j<mid;j++){
                int x=a[i+j],y=1ll*a[i+j+mid]*w[k]%mod;
                a[i+j]=add(x,y);a[i+j+mid]=sub(x,y);
            }
        }
    }
}
inline void DIT(poly &a){
    int n=a.size();
    for(int mid=1;mid<n;mid<<=1){
        for(int i=0,k=0;i<n;i+=mid<<1,k++){
            for(int j=0;j<mid;j++){
                int x=a[i+j],y=a[i+j+mid];
                a[i+j]=add(x,y);a[i+j+mid]=1ll*sub(x,y)*w[k]%mod;
            }
        }
    }
    int inv=qpow(n,mod-2);
    for(int i=0;i<n;i++)a[i]=1ll*a[i]*inv%mod;
    reverse(a.begin()+1,a.end());
}
inline poly operator*(poly f,poly g){
    int n=f.size(),m=g.size();
    get(n+m);
    f.resize(wl),g.resize(wl);
    DIF(f);DIF(g);
    for(int i=0;i<wl;i++)f[i]=1ll*f[i]*g[i]%mod;
    DIT(f);
    f.resize(n+m-1);
    return f;
}
inline poly move(poly a,int k){
    int n=a.size();get(n<<1);
    poly b(n);
    for(int i=0,pw=1;i<n;i++,pw=1ll*pw*k%mod){
        a[i]=1ll*a[i]*jc[i]%mod;
        b[i]=1ll*Inv[i]*pw%mod;
    }
    reverse(a.begin(),a.end());
    a=a*b;a.resize(n);
    reverse(a.begin(),a.end());
    for(int i=0;i<n;i++)a[i]=1ll*a[i]*Inv[i]%mod;
    return a;
}
int n;
long long m;
int main(){
    scanf("%d%lld",&n,&m);m%=mod-1;n++;init(n<<1);
    poly a(n);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    a=move(a,1);
    for(int i=0;i<n;i++)a[i]=1ll*a[i]*qpow(inv[i+1],m)%mod;
    a=move(a,mod-1);
    for(int i=0;i<n;i++)printf("%d ",a[i]);puts("");
    return 0;
}

标签:5010,frac,int,dp,冲刺,国赛,510,include,模拟
From: https://www.cnblogs.com/gtm1514/p/17425405.html

相关文章

  • QQ模拟
    1. 为什么选择这个项目  6842. 项目开发流程  6852.2 需求分析  6861.用户登录2.拉取在线用户列表3.无异常退出(客户端、服务端)4.私聊5.群聊6.发文件7.服务器推送新闻3.界面设计3.1 用户登录3.2 拉取在线用户列表3.3 私聊3.4 群聊3.5 发文件3.6 文件服务器推送新闻......
  • 5.22 字符串专题模拟赛
    T1P7469[NOIOnline2021提高组]积木小赛签到题,考虑固定\(\texttt{Bob}\)的左端点,双指针去判断是否匹配即可,时间复杂度\(O(n^2)\)。T2P7114[NOIP2020]字符串匹配考虑到\(AB\)必然是一个前缀,枚举\(AB\)长度\(len\),\(C\)的长度只有\(\lfloor\dfrac{n-len}{l......
  • 第二次冲刺5
    刘家诚:田铭庚:黄敏仪:今天我把web页面进行了美化处理,对表单元素以及表格都通过layui提供的框架进行优化处理,添加了新的数据表单,用来添加临时的员工调动消息,但是还没把之间的逻辑关系联系起来。......
  • 第二次冲刺4
    刘家诚:田铭庚:今天我对安卓端的通知功能进行了相关的学习和练习,在练习过程中,我对通知功能与数据库调用之间联系提出了相关的疑问,并且在网络上找到了相关的解答,我的实现逻辑是:在web界面数据库修改成功后,会在手机端添加一个函数用来记录web单独的修改次数,并且在web修改成功后,对通知......
  • 锁存器 模拟
    https://www.falstad.com/circuit/circuitjs.html这是一个电路模拟网站,把下面的sr.json保存,再点开这个网站,打开这个json文件就可以进行模拟sr.json$10.0000051.50042475847525550550w3681603681920w3681922562560w3682883682560w2561923682560w25......
  • 2023冲刺国赛模拟 6.0
    T1染色我们按照深度分别进行考虑,设当前考虑的深度为\(x\),考虑一种暴力的做法是设\(f_u\)表示将\(u\)节点内所有深度为\(x\)的点全部涂黑的最小代价,显然有转移\(f_u=\min(\sumf_v,a_{x-deep_u})\),正解考虑将深度为\(x\)的点取出来建立虚树,容易发现一个点代表原树一......
  • 2023冲刺国赛模拟6
    A.染色发现一条链的话等同于对一个区间取\(min\)长剖,记录取\(min\)的次数和推到的位置,使用\(st\)表辅助处理每次合并将取\(min\)推到较短长度code#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;typedefunsignedlonglongull;typedefp......
  • 冲刺国赛模拟 6
    长剖调不出来喜提垫底!评价:同比赛编号。牛子老师给出三道原题题号:qoj5418、5146、2303。染色简单长剖,为啥没有调出来呢?不懂。首先按深度考虑,设\(dp_{x,i}\)为在\(x\)把子树深度\(i\)染完的最小代价,转移显然\[dp_{x,i}=\min(\sum_{v}dp_{v,i-1},a_i)\]这玩意和深度有关......
  • 程序设计进阶模拟试题
    题目描述程序定义了NxN的二维数组,并在主函数中自动赋值。请编写函数fun,函数的功能是:使数组右上三角元素中的值乘以m。#include<stdio.h>#include<conio.h>#include<stdlib.h>#defineN5intfun(inta[][N],intm)/不得改动此注释文字及位置,begein/{}/不得改动此注释文字......
  • 2022.11.24 NOIP模拟赛
    A.不降序列题目描述lzx2005了解到有一种在\(O(n\logn)\)的时间复杂度内求出一个序列\(a\)的最长不下降子序列的方法如下:维护一个序列\(b\),初始时为空。依次考虑\(a_1,a_2,\ldots,a_n\),当考虑到\(a_i\)时,求出序列\(b\)中第一个比\(a_i\)大的元素,然后使用\(a_i......