2019年7月26日(数学、DP)

难受,爆零!!

哎……讲题吧

prob1:A

题目大意:两种操作:把某数二进制上某一位翻转或异或一个集合中的一个数,求从\(s\)变到\(t\)的最少步数

\(sb\)题,完完全全的水题,结果\(bfs\)的队列写萎了

第一种操作可以转成第二种,而每个数最多只被异或一次,一通\(bfs\)瞎搞就可以了。但最小步数更新需在入队时,并将是否更新作为入队条件,否则会\(T,RE\)炸掉(别问我怎么知道的)

贴代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;++i)
#define int long long
#define xx 270000
const int mod=998244353;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    for(;!isalnum(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
int que[xx][3];
int q[xx],all,ans[xx];
inline void bfs()
{
    int head=0,tail=-1;
    que[++tail][0]=0;
    que[tail][1]=0;
    que[tail][2]=0;
    while(head<=tail)
    {
        int w=que[head][0],u=que[head][1],v=que[head++][2];
        fur(i,w+1,all)
        {
            if(!ans[u^q[i]])
            {
                que[++tail][0]=i;
                que[tail][1]=u^q[i];
                ans[u^q[i]]=v+1;
                que[tail][2]=v+1;
            }
        }
    }
}
signed main()
{
    int t=in;
    q[1]=1;
    fur(i,2,18) q[i]=q[i-1]<<1;
    while(t--)
    {
        int n=in,m=in;all=18;
        fur(i,1,n) q[++all]=in;
        int res=0;
        memset(ans,0,sizeof(ans));
        bfs();
        ans[0]=0;
        fur(i,1,m)
        {
            int s=in,tt=in;
            res=(res+i*ans[s^tt]%mod)%mod;
        }
        printf("%lld\n",res);
    }
    return 0;
}

prob2:B

题目大意:给定一串字符串(仅存在英文26个字母),求最短的中字典序最小的非子序列字符串

开始以为是字符串题,后来以为是图论题,怎么都没想到是贪心+\(DP\)题(学姐狠啊),当字符串大小小于26时,可以很清楚得到答案,通过此性质从后往前\(DP\):

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;++i)
#define fdr(i,a,b) for(int i=a;i>=b;--i)
#define xx 500010
#define inf 0x7fffffff
int f[xx][27],g[xx],pos[xx],n;
char ch[xx];
inline void dfs(int q,int len)
{
    if(len==1)
    {
        fur(i,1,26)
        {
            if(f[q][i]==n+1)
            {
                printf("%c",i+'a'-1);
                return;
            }
        }
    }
    fur(i,1,26)
    {
        if(g[f[q][i]]==len)
        {
            printf("%c",i+'a'-1);
            dfs(f[q][i]+1,len-1);
            break;
        }
    }
}
int main()
{
    scanf("%s",ch+1);
    n=strlen(ch+1);
    fur(i,1,26) f[n+1][i]=n+1,pos[i]=n+1;
    g[n+1]=1;
    fdr(i,n,1)
    {
        fur(j,1,26) f[i][j]=f[i+1][j];
        f[i][ch[i]-'a'+1]=i;
        g[i]=inf;
        fur(j,1,26) g[i]=min(g[i],g[pos[j]]+1);
        pos[ch[i]-'a'+1]=i;
    }
    int ans=inf;
    fur(i,1,26)
    {
        if(f[1][i]==n+1)
        {
            printf("%c\n",i+'a'-1);
            return 0;
        }
        ans=min(ans,g[f[1][i]]);
    }
    dfs(1,ans);
    printf("\n");
    return 0;
}

prb3:C

题目大意:给定\(n*m\)矩阵,求三点对三点共线的方案数

考试时式子推错,不想说什么了

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;++i)
#define int long long
const int xx=1e7+10;
const int n6=166666668;
const int mod=1e9+7;
int phi[xx],prime[xx],cnt=0,ans=0,m,n;
bool mark[xx];
inline void handle()
{
    phi[1]=1;
    fur(i,2,n)
    {
        if(!mark[i]) phi[i]=i-1,prime[++cnt]=i;
        for(int j=1;j<=cnt&&prime[j]*i<=n;++j)
        {
            mark[i*prime[j]]=true;
            if(i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1);
            else
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
        }
    }
}
inline int calc(int x,int d,int u){return (x-u*d+x-d)*u/2%mod;}
inline int C(int nm){return nm*(nm-1)%mod*(nm-2)%mod*n6%mod;}
signed main()
{
    scanf("%lld%lld",&n,&m);
    if(n>m) swap(n,m);
    --n;--m;
    handle();
    fur(i,1,n)
    {
        int tmp=phi[i];
        tmp=(tmp*calc(n+1,i,n/i))%mod;
        tmp=(tmp*calc(m+1,i,m/i))%mod;
        ans=(ans+tmp)%mod;
    }
    ans=(ans-((n+1)*n/2%mod)*((m+1)*m/2%mod)%mod+mod)%mod;
    ans=(ans<<1)%mod;
    ans=(ans+(n+1)*C(m+1)%mod+(m+1)*C(n+1)%mod)%mod;
    printf("%lld\n",ans);
    return 0;
}

prob4:D

题目大意:给定\(n\)个标号结点所组成的任意图,求图中存在树的个数的\(k\)次方的和

知识储备:第二类斯特林数+prufer序列

而且上课心情不好,也没有认真听讲,导致这题不会,标程也没看懂,直接\(kuai\)学姐\(std\)算了。

(这压行真恶心):

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define LL long long
#define N 50005
using namespace std;

const int mo=998244353,G=3;
int n,K,rev[N*3],len,num,g[25][N];
LL S[25][25],jc[N],ny[N],wn[50],f[N*3],h[N*3],ans;

LL qp(LL x,LL y) {
    LL res=1;
    for(;y;y>>=1ll,x=x*x%mo)
        if(y&1ll) res=res*x%mo;
    return res;
}
void pre() {
    jc[0]=ny[0]=1;
    for(int i=1;i<=n;++i) jc[i]=jc[i-1]*i%mo;
    ny[n]=qp(jc[n],mo-2);
    for(int i=n-1;i>=0;--i) ny[i]=ny[i+1]*(i+1)%mo;
    f[1]=1*ny[0];
    for(int i=2;i<=n;++i) f[i]=qp(i,i-2)*ny[i-1]%mo;
    S[0][0]=1;
    for(int i=1;i<=K;++i)
        for(int j=1;j<=i;++j)
            S[i][j]=(S[i-1][j]*j%mo+S[i-1][j-1])%mo;
    for(len=1,num=0;len<=n+n;len<<=1,num++);
    for(int i=1;i<len;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(num-1));
    for(int i=0;i<=45;++i) wn[i]=qp(G,(mo-1)/(1<<i));
}
void ntt(LL *x,int sign) {
    for(int i=0;i<len;++i) if(i<rev[i]) swap(x[i],x[rev[i]]);
    for(int k=2,e=1;k<=len;k<<=1,e++) {
        for(int i=0;i<len;i+=k) {
            LL *a=x+i,*b=x+i+(k>>1); LL u,v,w=1;
            for(int j=0;j<(k>>1);++j,w=w*wn[e]%mo) {
                u=a[j],v=b[j]*w%mo;
                a[j]=u+v; a[j]>=mo?a[j]-=mo:0;
                b[j]=u-v; b[j]<0?b[j]+=mo:0;
            }
        }
    }
    if(sign==-1) {
        int inv=qp(len,mo-2);
        for(int i=0;i<len;++i) x[i]=x[i]*inv%mo;
        reverse(x+1,x+len);
    }
}
LL C(LL x,LL y) {return x>=y?jc[x]*ny[y]%mo*ny[x-y]%mo:0;}
int main()
{
    scanf("%d%d",&n,&K);
    pre();
    g[0][0]=1; ntt(f,1);
    for(int i=1;i<=K;++i) {
        memset(h,0,sizeof(h[0])*len);
        for(int j=0;j<=n;++j) h[j]=1ll*g[i-1][j]*ny[j]%mo;
        ntt(h,1);
        for(int j=0;j<len;++j) h[j]=h[j]*f[j]%mo;
        ntt(h,-1);
        for(int j=1;j<=n;++j) g[i][j]=h[j]*jc[j-1]%mo;
    }
    for(int i=1;i<=n;++i) {
        LL tmp=qp(2,1ll*(n-i)*(n-i-1)/2ll)*C(n,i)%mo;
        for(int j=1;j<=K;++j) {
            ans+=g[j][i]*S[K][j]%mo*jc[j]%mo*tmp%mo;     //!!!!!
            ans>=mo?ans-=mo:0;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/ALANALLEN21LOVE28/p/11312991.html

时间: 2024-10-08 19:06:39

2019年7月26日(数学、DP)的相关文章

2019年2月26日【整理物品,下载收集考研资料,明天正式开始复习】

2019年1月26日星期六 一:一句话木马重学习 1.网站安全狗网马查杀 http://download.safedog.cn/download/software/safedogwzApache.exe 2.D盾 Web 查杀 http://www.d99net.net/down/WebShellKill_V2.0.9.zip 3 深信服WebShellKillerTool http://edr.sangfor.com.cn/tool/WebShellKillerTool.zip 4 BugSc

【2019年4月26日】最新指数基金估值表(坚持定投终能胜利)

(本篇文章阅读时间约2分钟) 大家好,我是牛九老师,专注于研究指数基金领域很多年,欢迎来到[牛九老师的投资者大家庭]. 每天我会给大家分享投资心得,发布最新的指数基金估值. 每天只需五分钟,大家跟随老师一起坚持投资自己.实现财富增值,战胜通货膨胀,共同走向财务自由之路,过上自己真正想要的生活! 我们坚持在每周四(下午三点之前)进行指数基金的定投,届时会向大家推荐当期的定投组合,强烈推荐大家在支付宝中购买基金,方便安全有保障! 下面是我为大家精心制作的2019年4月26日[第106期]指数基金估值

2019年6月26日:日历问题、整数求和、奇数求和

题目描述: 假设 2012 年 1 月 1 日是星期日,请求出 n 天后是星期几 输入描述: 多组输入每组输入一个正整数 n (1 <= n <= 2000) 输出描述: 对于每组输入,输出 1 个整数 i (1 <= i <= 7),表示 n 天后是星期几 样例输入: 1 2 样例输出: 1 2 #include<iostream> using namespace std; int main(){ int n; while(cin>>n) cout<

实验报告(2019年6月26日)

c程序实验报告 姓名:黄志乾????实验地点:教学楼514教室????实验时间:4月30日 一.本章要点 1.通过实验理解结构体和共用体的数据结构 2.结构体.共用体中数组的使用及变量的赋值 3.结构体和共用体定义时的嵌套使用(嵌套使用的结构体必须先定义) 二.实验内容 1.实验练习:9.1 问题描述:试利用结构体类型描述年.月.日,输入一个日期,统计该日期是本年度第多少天. 流程图 实验代码 #include<stdio.h> main() { struct date { int year,

2019年5月26日

距离考核结束的时间只剩下5天了,一个特别大的问题就是前后端的交流问题,不单单是项目的进度,更多的是人与人之间的交流.页面的进度完成了一整个流程,剩下的就是和后端的进行交互,后端的进度有点慢,导致我现在还没有真正意义上的完成过一次交互,但今天有前端的小伙伴说我写的页面的JavaScript有些没有实现完,我也是今天才发现这个问题,所以页面的进度不能说是完成了,我们也需要进行页面的改动,整个项目大体上说算是都没有完成.最最重要的也许就是组员们之间的交流问题了吧,没有进行及时的前后端交流,没有耐下心来

2019年5月26日-linux就该这么学-第11课

第9章 使用 ssh服务管理远程主机 9.1 配置网络服务9.1.1 配置网络参数--nmtui(1) 网卡配置文件中 ONBOOT yes,这样在系统重启后网卡就被激活了.(2) 手动重启服务:systemctl restart network:9.1.2 创建网络会话--网络会话功能允许用户在多个配置文件中快速切换.nmcli--基于命令行的网络配置工具,用于管理NetworkManager服务.(1) 查看网络连接情况:nmcli connection show:(2) 配置company

2019年7月26日星期五(文件IO)

一. 标准IO 1. 标准IO函数有什么特点? 标准IO函数都是封装在一个库中,这个库就是标准C库,标准C库头文件都是#include <stdio.h>,所以标准IO函数的头文件都是#include <stdio.h>,而且标准IO处理方式与系统IO不一样,读取/写入数据时,都有缓冲区. 2. 系统IO与标准IO作用对象? 系统IO对象  -> 硬件设备文件,例如: 访问LCD液晶,触摸屏,红外传感器,温湿度传感器.超声波传感器 标准IO对象  -> 普通文件,例如:

2019年8月26日至29日面试记录

话不多说,这是一次伤心的面试经历,有了面试机会,奈何自己不争气,面了几家,终于认清,还是自己太菜了,技术方面还是没有达到一定的水准,至少没有达到面试官感觉能用的水准.努力学习还是目前生活中的唯一主旋律.        总结这次面试遇到的问题(我面的是Java开发岗位)        1.基础肯定是要弄懂得,哪怕你真的不是能全记住,你面试前也要过一遍,加深一下记忆,面试中肯定会遇到.        2.后台框架,目前主流的框架你要知道,比如现在流行的spring boot ,spring clou

2019年10月26日 复习

描述符:描述对象的一种方法  __get__  __set__ __delete__  至少使用了其中一种. 描述符何时何地使用: 何地:定义成另一个类的类属性 何时:被描述的类在操作属性的时候会触发 描述符:1 没有set方法  叫做 非数据描述符 2 有get和set 叫做 数据描述符 优先级: 1类属性>2数据描述符>3实例属性>4非数据描述符>5找不到的属性触发getattr type 是python中内置的元类 原文地址:https://www.cnblogs.com/p