2019年9月14日(数论专题考试)

汗~,差点爆零\(QwQ\)……

\(prob2:saber\)

\(upd\):题意以后都不写了,反正写了日期,去文件里找。

题目数学?可惜我开始跑的是暴力……

思路肯定是总方案减去不合法方案,那么就有两种主流思路:

暴力30分,因为不合法情况是且仅是要到达灰线上面一条线的任一个点,那么可以算方案。考虑\(dp\)式,设\(f_i\)为到达目标线上的第\(i\)个点且未经过之前\(i-1\)个点的总方案数,\(s_i\)表示目标线上第\(i\)个点到起点的方案数,\(t_i\)表示目标线上第\(i\)个点到终点的方案数,\(p_{i,j}(i<j)\)表示目标线上第\(i\)个点到第\(j\)个点的方案数,则
\[f_i=s_i-\sum_{j=1}^{i-1}f_j* p_{j,i}\]
\[ans=C_{n+m}^m-\sum_{i=1}^mf_i* t_i\]
时间复杂度\(O(m^2)\),实际得分40分:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
const int mod=2e7-1;
const int xx=1e5+1612;
int jc[xx],ny[xx],f[xx];
inline int power(int x,int k)
{
    int res=1;
    for(;k;x=x*x%mod,k>>=1) if(k&1) res=res*x%mod;
    return res;
}
inline int C(int n,int m)
{
    return jc[n]*ny[m]%mod*ny[n-m]%mod;
}
jinitaimei main()
{
    int n=in,m=in;
    jc[0]=ny[0]=1;
    fur(i,1,n+m) jc[i]=jc[i-1]*i%mod,ny[i]=power(jc[i],mod-2);
    fur(i,0,m-1) f[i+1]=C(i+i+2,i);
    fur(i,1,m) fur(j,1,i-1) f[i]=(f[i]-f[j]*C((i-j)<<1,i-j)%mod+mod)%mod;
    int ans=C(n+m,n);
    fur(i,1,m) ans=(ans-f[i]*C(n-(i-1)+m-(i+1),n-(i-1))%mod+mod)%mod;
    cout<<ans<<endl;
    return 0;
}

正解,发现对称算一下\(ans=C_{n+m}^m-C_{n+m}^{m-2}\)
虽然\(n,m\)比较大,但发现\(mod=2e7-1\)比较小,于是卢卡斯

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
const int mod=2e7-1;
int jc[mod];
inline int power(int x,int k)
{
    int res=1;
    for(;k;x=x*x%mod,k>>=1) if(k&1) res=res*x%mod;
    return res;
}
inline int lucas(int n,int m)
{
    if(n<mod&&m<mod)
    {
        if(n<m) return 0;
        return jc[n]*power(jc[m],mod-2)%mod*power(jc[n-m],mod-2)%mod;
    }
    return lucas(n%mod,m%mod)*lucas(n/mod,m/mod)%mod;
}
jinitaimei main()
{
    int n=in,m=in;
    jc[0]=1;
    fur(i,1,mod) jc[i]=jc[i-1]*i%mod;
    cout<<(lucas(n+m,m)-lucas(n+m,m-2)+mod)%mod<<endl;
    return 0;
}

于是正解比暴力还短……

\(prob3:\)不够优秀(\(good\))

很明显发现这个东西其实是求\(\sum_{i=1}^nd_i* (d_i-1)/2\)

70分就是暴力求,时间复杂度\(O(n\sqrt n)\):

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
const int mod=998244353;
const int ny2=499122177;
inline int power(int x,int k)
{
    int res=1;
    for(;k;x=x*x%mod,k>>=1) if(k&1) res=res*x%mod;
    return res;
}
jinitaimei main()
{
    int n=in;
    if(n==1)
    {
        cout<<"0"<<endl;
        return 0;
    }
    int ans=0;
    fur(i,2,n)
    {
        int all=0,j=i;
        for(int k=1;k*k<=j;++k) if(!(j%k))
                             {
                                 ++all;
                                 if(k*k!=j) ++all;
                             }
        ans=((all-1)*all%mod*ny2%mod+ans)%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

正解线性筛即可,时间复杂度\(O(n)\):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
const int mod=998244353;
const int ny2=499122177;
int d[10000001],e[10000001];
int prime[10000001],n,ans=0,cnt=0;
bool to[10000001];
inline void init()
{
    fur(i,2,n)
    {
        if(!to[i])
        {
            prime[++cnt]=i;
            d[i]=2;
            e[i]=1;
        }
        fur(j,1,cnt)
        {
            if(i*prime[j]>n) break;
            to[i*prime[j]]=true;
            if(i%prime[j])
            {
                d[i*prime[j]]=d[i]*2;
                e[i*prime[j]]=1;
            }
            else
            {
                d[i*prime[j]]=d[i]/(e[i]+1)*(e[i]+2);
                e[i*prime[j]]=e[i]+1;
                break;
            }
        }
    }
}
jinitaimei main()
{
    n=in;
    init();
    fur(i,1,n) ans=(ans+d[i]*(d[i]-1)%mod*ny2%mod)%mod;
    cout<<ans<<endl;
    return 0;
}
  

\(prob1:\)摆干草(\(bales\))

额,没想到是数据结构……

二分,然后并查集维护最小区间,查看与现在搜到的是否矛盾即可

每当查到一个\(mid\),将\(mid\)及之前的按\(A\)值从大到小排序,查看是否有大区间覆盖小区间即可

这个二分有点毒瘤……

时间复杂度\(O(N\alpha NlogQ)\):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
//#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
const int xx=1e6+1612,yy=2e5+1612;
int fa[xx],n,m;
struct line
{
    int l,r;
    int val;
}L[yy],tmp[yy];
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline bool cmp(line x,line y){return x.val>y.val;}
inline bool check(int x)
{
    fur(i,1,n+1) fa[i]=i;
    fur(i,1,x) tmp[i]=L[i];
    sort(tmp+1,tmp+1+x,cmp);
    int l1,l2,r1,r2;
    l1=l2=tmp[1].l;r1=r2=tmp[1].r;
    fur(i,2,x)
    {
        if(tmp[i].val<tmp[i-1].val)
        {
            if(find(l1)>r1) return false;
            for(int j=fa[l2];j<=r2;j=fa[j]) find(j),fa[j]=find(j+1);
            l1=l2=tmp[i].l;
            r1=r2=tmp[i].r;
        }
        else
        {
            l1=max(l1,tmp[i].l);
            l2=min(l2,tmp[i].l);
            r1=min(r1,tmp[i].r);
            r2=max(r2,tmp[i].r);
            if(r1<l1) return false;
        }
    }
    if(find(l1)>r1) return false;
    return true;
}
jinitaimei main()
{
    freopen("bales.in","r",stdin);
    freopen("bales.out","w",stdout);
    n=in,m=in;
    fur(i,1,m) L[i]=(line){in,in,in};
    int l=1,r=m+1;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid)) l=mid+1;
        else r=mid;
    }
    if(l>m) puts("0");
    else printf("%d\n",l);
    return 0;
}

\(prob4:\)闷声发大财(\(rich\))

30分:考虑状压,明确状态\(f_{A,B}\)为龙选\(A\)而\(hyj\)选\(b\)的方案数,压的是因数

压根没想到,于是没写,不给代码了……

正解:考虑状压优化,将\(2-n\)的每个数\(i\)的\(\sqrt i\)之内的质因数状压出来,其余暴力枚,用数组\(f_{0/1,A,B}\)表示即为龙或\(hyj\)选了当前数\(i\)的大于\(\sqrt i\)的那一个质因数且龙集合\(A\)、\(hyj\)集合\(B\)的方案数,可以推出来递推式……

在\(\sqrt {500}\)以内的质数只有\(8\)个,可以放心状压……

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
const int maxp(8),maxn(501);
int prime[8]={2,3,5,7,11,13,17,19};
int n,mod,ans=0;
int f[2][1<<maxp][1<<maxp],g[1<<maxp][1<<maxp];
struct number{int numset,bignum;}a[maxn];
inline bool cmp(number x,number y){return (x.bignum^y.bignum)?(x.bignum>y.bignum):(x.numset<y.numset);}
inline void up(int &x,int y){(x+=y)%=mod;}
inline void init()
{
    n=in;mod=in;
    fur(i,2,n)
    {
        int x=i;
        fur(j,0,7) if(!(x%prime[j]))
        {
            a[i].numset+=(1<<j);
            while(!(x%prime[j])) x/=prime[j];
        }
        a[i].bignum=x;
    }
    sort(a+2,a+n+1,cmp);
    g[0][0]=1;
}
inline void sol()
{
    fur(i,2,n)
    {
        if(i==2||a[i].bignum==1||a[i].bignum^a[i-1].bignum) memcpy(f[0],g,sizeof(g)),memcpy(f[1],g,sizeof(g));
        fdr(j,(1<<maxp)-1,0) fdr(k,(1<<maxp)-1,0)
        {
            if(!(j&a[i].numset)) up(f[0][j][k|a[i].numset],f[0][j][k]);
            if(!(k&a[i].numset)) up(f[1][j|a[i].numset][k],f[1][j][k]);
        }
        if(i==n||a[i].bignum==1||a[i].bignum^a[i+1].bignum)
            fdr(j,(1<<maxp)-1,0) fdr(k,(1<<maxp)-1,0) g[j][k]=(f[0][j][k]+f[1][j][k]-g[j][k]+mod)%mod;
    }
}
jinitaimei main()
{
    init();
    sol();
    fdr(j,(1<<maxp)-1,0) fdr(k,(1<<maxp)-1,0) if(!(j&k)) up(ans,g[j][k]);
    cout<<ans<<endl;
    return 0;
}

\(ps:xg\)真是一只毒瘤的鸡

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

时间: 2024-11-08 20:35:21

2019年9月14日(数论专题考试)的相关文章

2019年8月14日星期三(系统编程)

2019年8月14日星期三 一.线程属性  -> 分离属性 1. 什么是分离属性? 分离: 说明主线程不需要接合子线程  -> 不需要pthread_join子线程  -> 当主线程退出时,子线程还是会退出. 非分离: 说明主线程需要接合子线程  -> 需要pthread_join子线程 默认pthread_create()创建出来的线程都是非分离属性. 2. 如何创建出分离属性的线程呢? 思路: 添加分离属性到一个属性变量中,然后使用该属性变量去创建一个新的线程,那么这个线程就是

2019年9月14日

今天写完了毕业设计开题报告第一版并更新到了github:https://github.com/chengchuancc/Graduation-Project 找工作依旧让人脑壳疼:目前为止海康威视.景嘉微.信维通信都把我淘汰了,其他的大企业在投了简历之后也杳无音信   今天开始复习结构方面的知识:材料力学.互换性.FDMA,为笔试做准备 2019年9月14日 原文地址:https://www.cnblogs.com/chengchuan/p/11519680.html

2019年8月14日 卫星导航定位相关知识点

---恢复内容开始--- 基带信号处理流程>>>>>>: 接收机主要的两个过程:捕获和跟踪.    捕获过程完成对信号载波频率及PRN码码相位的粗略估计,为跟踪过程提供初始值,跟踪算法则完成对两者的精确估计.接收机必须捕获和跟踪多个导航卫星信号中的伪随机码和载波,才能完成定位.测速和授时的功能.    信号的捕获和跟踪处理是接收机的关键部分. About捕获: 捕获的目的就是确定可见卫星及卫星信号的载波频率.码相位的粗略值. 导航信号采用码分多址(CDMA)技术,采用不

2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller 模型-视图-控制器)是一种Web架构的模式,所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器(C)接受用户的输入调用模型和视图完成用户的请求. M

2019年12月14日 Springboot项目搭建(2)-整合静态文件

1,引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> 2,添加静态文件 3,测试 原文地址:https://www.cnblogs.com/excellencesy/p/12069067.html

2014年11月12~11月14日,杨学明老师《软件测试管理》内训在北京某银行软件中心成功举办!

2014年11月12~11月14日,北京天气呈现少有的APEC蓝,著名研发管理专家杨学明老师为某银行提供了三天的内训服务,此次培训由两部分组成,第一部分是<软件测试管理高级实务>.第二部分是<软件测试需求分析和测试设计>,三天的培训非常紧张,包括老师讲解,案例演练,专题研讨,过程衔接非常紧密,课堂气氛也比较轻松,来自该银行核心系统和网银两个事业部的同事参加了此次培训,包括开发,需求,测试和维护人员等,课程结束后,举行了考试,大家对三天的学习进行回顾和总结,并准备把这两天学习到知识结

开机时自动启动的AutoHotkey脚本 2019年07月08日19时06分

;;; 开机时自动启动的AutoHotkey脚本;; 此脚本修改时间 2019年06月18日20时48分;; 计时器创建代码段 -----------------------------------------------------------------------------------------; SetTimer可以模拟多线程从而不影响主线程的流畅执行; 请在SciTE4AutoHotkey中选中单词并按快捷键F12跳转到函数定义处; 绿色免安装程序,统一都分类保存在本地磁盘D分区文

周记 - 2019年11月03日

2019年11月05日 2019年徐州区域赛结束了.封榜前3题铜牌前部,封榜后最后27分钟罚了4次通过E题.虽然4题罚时爆炸,不过万幸得了银牌后部.目前看应该还会再参加一年的,这个博客会不断更新记录最后一年参加比赛的学习进度(以及最后两年本科的其他事情),今年的目标是做一个真正的全能选手,首先希望在寒假结束前把Codeforces打到橙色(2100+),证明自己思维还行吧. 既然想做全能选手,每个专题都要学到省选级别吧,学习的分类就参照OI-Wiki的分类,题单的话,模板题从洛谷找,思维题从Co

2019年12月8日 运飞龙 linux

1.system v init运行级别及作用 init运行级别                  作用 0                                  关机 1                                  单用户模式 2                                  多用户的文本界面 3                                  多用户的文本界面 4