THUSC十二题

以下顺序不代表难度,只是按照本人的做题顺序。


解密运算

link
首先有一个正确性显然,但是不好解释的做法,用样例举个例子:

\[\begin{bmatrix} &\dots&&1\\ &\dots&&1\\ &\dots&&1\\ &\dots&&3\\ &\dots&&0\\ &\dots&&1\\ &\dots&&2\\ \end{bmatrix} \]

最右边这一行表示每一种字符串的排名,这里我们只知道最后一个。
但是,我们也可以根据排名得到每一个字符串的第一个是什么。

\[\begin{bmatrix} 0&\dots&&1\\ 1&\dots&&1\\ 1&\dots&&1\\ 1&\dots&&3\\ 1&\dots&&0\\ 2&\dots&&1\\ 3&\dots&&2\\ \end{bmatrix} \]

此时可以发现,根据末尾和第一个字符,我们又可以得到 \(n\) 种长度为 \(2\) 的字符,把它们按照字典序依次填入

\[\begin{bmatrix} 0&1&\dots&&1\\ 1&0&\dots&&1\\ 1&1&\dots&&1\\ 1&1&\dots&&3\\ 1&2&\dots&&0\\ 2&3&\dots&&1\\ 3&1&\dots&&2\\ \end{bmatrix} \]

继续填下去,可以发现到最后能直接填完整个矩阵,其中以 \(0\) 结尾的那个就是答案。
至此,已经得到了一个 \(O(n^2)\) 的做法,已经有 \(60\) 分了。

接下来考虑优化。
可以发现的是,每一次操作之后,每一个字符串转移的对应位置都是固定的,比如上面的例子中第五行的字符串每一次都会往第一行转移,而第一行的每次都往第二行转移......
这是因为字典序的特点,因此每个字符串的大小关系早在第一次就已经确定了。
可以考虑事先求出转移数组来,然后从以 \(0\) 结尾的那个字符串开始反推回去,求出这一行上每一个元素是从哪一行转移过来的。
不难想到可以倍增处理,复杂度 \(O(n \log n)\)

Code
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
	bool f=true;ll x=0;
	register char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	if(f) return x;
	return ~(--x);
}
il int read(char *s){
	int len=0;
	register char ch=getchar();
	while(ch==' '||ch=='\n') ch=getchar();
	while(ch!=' '&&ch!='\n'&&ch!=EOF) s[++len]=ch,ch=getchar();
	return len;
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
int n,m;
const int MAXN=2e5+7;
int a[MAXN];
// .的存在可以确定原本的字符串中的末尾  
// 确定了末尾之后是不是可以通过末尾来得到整个字符串呢?  
// 假设当前的末尾是x,怎么往后得到更多的信息?  
// 目前已经知道的信息是末尾,以及每一个区间所对应的字符区间   。
// 比较蠢的一个做法是去枚举这个区间的放置关系,但是很显然复杂度是错的,而且找不到什么策略  。
// 那么尝试照着之前的样子构造一下。  
// a_{1}.........。  
//这样看上去可以从后往前推,但是一看就很不对劲  
//重复的字符集很麻烦啊。。。。。。
// 是dp吗?  
// 看上去有20分是在白给,保证互不相同的时候已经可以从后往前推了  
// 可以建图倍增......
int f[21][MAXN];
int rk[MAXN];
int query(int u,int dis){
	int res=0;
	for(ri i=20;~i;--i){
		if(res+(1<<i)<=dis){
			u=f[i][u];
			res+=(1<<i);
		}
	}
	if(res!=dis){
		u=f[0][u];
	}
	return u;
}
#define pii pair<int,int>
pii b[MAXN];
int main(){
	n=read(),m=read();
	for(ri i=1;i<=n+1;++i) a[i]=read(),b[i].first=a[i],b[i].second=i;
	sort(b+1,b+n+1+1);
	for(ri i=1;i<=n+1;++i) f[0][i]=b[i].second;
	for(ri i=1;i<=20;++i){
		for(ri j=1;j<=n+1;++j){
			f[i][j]=f[i-1][f[i-1][j]];
		}
	}
	int now=0;
	for(ri i=1;i<=n+1;++i){
		if(a[i]==0){
			now=i;
			break;
		}
	}
	for(ri i=1;i<=n;++i){
		// print(f[0][i]);
		write(a[query(now,i)]),putchar(' ');
		// printf("%d %d\n",i,query(now,i));
	}
	return 0;
}

当然,其实可以直接从前往后直接扫一遍,时空复杂度均为 \(O(n)\)

异或运算

link
看到这种异或求第 \(k\) 大的题目,第一反应肯定是线性基 Trie树。
可以发现的是 \(q,n\) 都很小,因此可以考虑对 \(m\) 这一维维护一个可持久化Trie树,然后每次去二分答案,复杂度 \(O(m\log^2 V+ nq \log^2 V)\),稍微松一下的话可以拿到 \(90\) 分。
复杂度的瓶颈在于二分答案,这个过程其实是可以优化的。
可以发现,在Trie树上判断的过程,其实就是一个二分的过程,而且答案是从高位到低位依次确定的。
具体地说,每一次统计一下如果让这一位取零之后的答案会不会比 \(k\) 大,根据这个来决定这一位是 \(0\) 还是 \(1\) ,并决定 trie 树上的下一个结点。
这一部分还是看代码比较好理解一些,不过如果知道二分的做法的话这一部分也应该能很轻松地想明白。

Code
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
#define getchar() (p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
char ou[1<<22],buf[1<<22],*p1=buf,*p2=buf;
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
int n,m;
#define lc t[u].c[0]
#define rc t[u].c[1]
const int MAXN=3e5+7;
struct T
{
    int sum,c[2];
}t[MAXN<<6];
ui base[32];
int cnt;
void insert(int &u,ui v,int lst,int dep=30){
    if(!u) u=++cnt;
    if(dep==-1){
        t[u].sum++;
        return;
    }
    if(v&base[dep]){
        lc=t[lst].c[0];
        rc=++cnt;
        t[rc]=t[t[lst].c[1]];
        insert(rc,v,t[lst].c[1],dep-1);
    }
    else{
        rc=t[lst].c[1];
        lc=++cnt;
        t[lc]=t[t[lst].c[0]];
        insert(lc,v,t[lst].c[0],dep-1);
    }
    t[u].sum=t[lc].sum+t[rc].sum;
}
ui a[1024];
int root[MAXN];
ui pos[1024][2];
int solve(int l,int r,int u,int d,int k){
    int tot=0;
    ui ans=0;
    for(ri i=l;i<=r;++i){
        pos[i][0]=root[u-1];
        pos[i][1]=root[d];
    }
    for(ri dep=30;~dep;--dep){
        int sum=0;
        for(ri i=l;i<=r;++i){
            int typ=a[i]>>dep&1;
            sum+=t[t[pos[i][1]].c[typ]].sum-t[t[pos[i][0]].c[typ]].sum;
        }
        int f=(sum+tot<k);
        if(f){
            tot+=sum;
            ans|=base[dep];
        }
        for(ri i=l;i<=r;++i){
            int typ=a[i]>>dep&1;
            pos[i][0]=t[pos[i][0]].c[typ^f];
            pos[i][1]=t[pos[i][1]].c[typ^f];
        }
    }
    return ans;
}
int main(){
    // freopen("P5795_10.in","r",stdin);
    // freopen("1.out","w",stdout);
    n=read(),m=read();
    base[0]=1;
    for(ri i=1;i<=30;++i) base[i]=base[i-1]<<1;
    for(ri i=1;i<=n;++i) a[i]=read();
    for(ri i=1;i<=m;++i) root[i]=i;
    cnt=m;
    for(ri j=1;j<=m;++j){
        ui b=read();insert(root[j],b,root[j-1]);
    }
    int tt=read();
    for(ri i=1;i<=tt;++i){
        int l=read(),r=read(),u=read(),d=read(),k=(d-u+1)*(r-l+1)-read()+1;
        print(solve(l,r,u,d,k));
    }
    return 0;
}

平方运算

link
看到这几个模数,猜测是否是循环节。
打表之后,可以发现每一个循环节的 \(lcm\) 长度不会超过60。
因此,可以直接建线段树维护。
因为代码非常屎,咕了

补退选

link
非常一眼的一道trie树。
暴力做法自然是对每一个点维护一个类似于单调栈的东西,但是可以发现连栈都不需要维护,只要一个tag记录目前已经被删除了几个,删除和加入操作是可以互相抵消的。
同时再开一个vector,下标 \(p\) 所对应的值表示目前这个前缀最早出现 \(p\) 次的时间戳。
每次修改就直接暴力往上改,或者在插入的时候直接一路上一起修改就可以了。
时间复杂度 \(O(\sum|S|)\),空间复杂度再算上一个字符集。

Code
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
const int MAXN=1e5+7;
struct T
{
    int c[10],tag;
    vector<int> p;
}t[MAXN*60];
int cnt;
char s[64];
il void insert(int &u,int dep,int len,int id){
    if(!u) u=++cnt;
    if(!t[u].tag) t[u].p.push_back(id);
    else t[u].tag--;
    if(dep==len) return;
    insert(t[u].c[s[dep]-'a'],dep+1,len,id);
}
il void del(int &u,int dep,int len,int id){
    t[u].tag++;
    if(dep==len) return;
    del(t[u].c[s[dep]-'a'],dep+1,len,id);
}
il int query(int len,int pos){
    int u=1;
    for(ri i=0;i<len;++i) u=t[u].c[s[i]-'a'];
    if(t[u].p.size()>pos) return t[u].p[pos];
    else return -1;
}
int root;
ll ans;
int main(){
    int tt=read();
    for(ri i=1;i<=tt;++i){
        int typ=read();
        scanf("%s",s);
        int len=strlen(s);
        if(typ==3){
            ll a=read(),b=read(),c=read();
            ll res=query(len,(a*abs(ans)+b)%c);
            print(ans=res);
        }
        else{
            if(typ==1) insert(root,0,len,i);
            else del(root,0,len,i);
        }
    }
    return 0;
}

感觉是这12道里最简单的一道了

成绩单

区间dp不知道为什么是黑题
首先对序列做一个离散化。
然后令 \(f_{l,r,x,y}\) 表示让当前区间的最小值为 \(x\) ,最大值为 \(y\) 的最小代价是多少, \(g_{l,r}\) 表示区间 \([l,r]\) 全部发完的最小答案是多少。
不难得到下面这样两个转移:

\[\begin{aligned} &f_{l,r+1,\min(x,w_{r+1}),\max(y,w_{r+1})}=\min(f_{l,r+1,\min(x,w_{r+1}),\max(y,w_{r+1})},f_{l,r,x,y}) \\ &f_{l,r,x,y}=\min(f_{l,k,x,y}+g_{k+1,r}),k\in[l,r) \\ &g_{l,r}=\min(f_{l,r,x,y}+A+B(y-x)^2)\\ \end{aligned} \]

最后的答案即为 \(g_{1,n}\)

Code
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
ll f[64][64][64][64],g[64][64],a,b,n,w[64],ans;
/*
区间dp的话 
大概是有个n^4的
还要查询区间max和区间min  
*/
vector<ll> vec;
il ll spw(ll x){return x*x;}
int main(){
    // freopen("rand.in","r",stdin);
    // freopen("1.out","w",stdout);
    memset(f,0x3f,sizeof(f));
    memset(g,0x3f,sizeof(g));
    n=read();
    a=read(),b=read();
    vec.push_back(0);
    for(ri i=1;i<=n;++i){
        w[i]=read();
        vec.push_back(w[i]);
    }
    sort(vec.begin(),vec.end());
    vec.erase(unique(vec.begin(),vec.end()),vec.end());
    for(ri i=1;i<=n;++i){
        w[i]=lower_bound(vec.begin(),vec.end(),w[i])-vec.begin();
        f[i][i][w[i]][w[i]]=0;
    }
    int top=vec.size()-1;
    for(ri len=1;len<=n;++len){
        for(ri l=1,r=l+len-1;r<=n;++l,++r){
            for(ri x=1;x<=top;++x){
                for(ri y=x;y<=top;++y){
                    f[l][r][min(w[r],x)][max(w[r],y)]=min(f[l][r][min(w[r],x)][max(w[r],y)],f[l][r-1][x][y]);
                    for(ri k=l;k<r;++k){
                        f[l][r][x][y]=min(f[l][r][x][y],f[l][k][x][y]+g[k+1][r]);
                    }
                }
            }
            for(ri x=1;x<=top;++x){
                for(ri y=x;y<=top;++y){
                    g[l][r]=min(g[l][r],f[l][r][x][y]+a+b*spw(vec[y]-vec[x]));
                }
            }
        }
    }
    print(g[1][n]);
    return 0;
}

空间复杂顿为 \(O(n^4)\),时间复杂度为 \(O(n^5)\)


从这里开始,画风就变得不一样起来了。

星露谷物语

看到标题还以为会是大模拟,结果是一道随机化题。
这题非常没有素质
连个题解都搜不到
稍微试着写了个退火,能拿四五十分的样子。
还有很多优化可以加。
先去重之后对每一个DAG内虽然没说,但是猜它是DAG跑一次最小生成树,可以构造出方案使得除了直径每条边走两次。
然后用退火去搞一下这个访问树的顺序,应该可以优化很多,甚至有机会过。

不过懒得写了,之前写的骗分退火也找不到了

巧克力

神仙题+1

这种题放在D1T1的位置真的好吗
首先,确保你会斯坦纳树,不然

一切都百搭

先不管中位数的问题,这个很显然是拿来二分的。
先考虑如何求最少块数。
我们对每一种颜色赋一个 \([1,k]\) 之间的值,然后以 \(k\) 个值为关键点跑斯坦纳树,不难发现只有当最后答案所选取的 \(k\) 种颜色所赋的值互不相同的时候才是对的。
可以得到每一次正确的概率是 \(\frac{k!}{k^k}\) ,当 \(k=5\) 的时候正确率最低,为 \(3.84 \%\)
非常低啊,但是没关系,可以多做几次。
当重复这个操作100次之后,正确率大概是 \(1-(1-3.84 \% )^{100}=98 \%\) ,已经相当高了。当然,如果想要A了这道题的话可能还需要再多提交几次

时间复杂度 \(O(t \times T\log (nm)(nm\log(nm) 2^k+3^k))\),其中 \(t\) 是操作次数。
但是 SPFA 在这种无负权边的网格图上跑得飞快,最慢的点做 \(120\) 次也只需要200ms左右。

Code
#include<cstdio>
#include<vector>
#include<cmath>
#include<deque>
#include<algorithm>
#include<cstring>
#include<ctime>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
int n,m,k;
const int MAXN=256;
int f[1<<5][MAXN];
int id(int x,int y){return (x-1)*m+y;}
struct edge
{
    int u,w;
};
vector<edge> g[MAXN];
int w1[]={0,0,1,-1};
int w2[]={1,-1,0,0};
int a[MAXN][MAXN],c[MAXN][MAXN];
int p[MAXN],mark[MAXN],vis[MAXN];
int q[8192];
void SPFA(int *f){
    int l=4000+1,r=4000;
    for(ri i=1;i<=n*m;++i) 
        mark[i]=1,q[++r]=i;
    while(r>=l){
        if(q[l]>q[r]) swap(q[l],q[r]);
        int u=q[l];++l;
        mark[u]=0;
        for(ri i=0;i<g[u].size();++i){
            edge e=g[u][i];
            if(f[e.u]>f[u]+e.w){
                f[e.u]=f[u]+e.w;
                if(!mark[e.w]){
                    if(f[e.u]>f[q[l]]) q[++r]=e.u;
                    else q[--l]=e.u;
                    mark[e.u]=1;
                }
            }
        }
    }
}
int O;
int w[MAXN],to[MAXN];
int vec[MAXN],top;
void lsh(){
    top=0;
    for(ri i=1;i<=n;++i){
        for(ri j=1;j<=m;++j){
            vec[++top]=a[i][j];
        }
    }
    sort(vec+1,vec+top+1);
    top=unique(vec+1,vec+top+1)-vec-1;
    for(ri i=1;i<=n;++i){
        for(ri j=1;j<=m;++j){
            a[i][j]=lower_bound(vec+1,vec+top+1,a[i][j])-vec;
        }
    }
}
int ans;
void work(){
    // p[76]=0,p[46]=1,p[1]=2,p[180]=3,p[174]=4;
    memset(f,0x3f,sizeof(f));
    for(ri i=1;i<=n;++i){
        for(ri j=1;j<=m;++j){
            int u=id(i,j);
            if(~c[i][j]){
                f[1<<p[c[i][j]]][u]=1;
            }
        }
    }
    for(ri i=1;i<=n*m;++i) g[i].clear();
    for(ri i=1;i<=n;++i){
        for(ri j=1;j<=m;++j){
            if(c[i][j]==-1) continue;
            for(ri l=0;l<4;++l){
                int x=i+w1[l],y=j+w2[l];
                if(x<1||x>n||y<1||y>m||c[x][y]==-1) continue;
                int u=id(i,j),v=id(x,y);
                g[u].push_back((edge){v,1});
            }
        }
    }
    for(ri s=0;s<(1<<k);++s){
        for(ri t=s;t;t=(t-1)&s){
            for(ri i=1;i<=n*m;++i){
                f[s][i]=min(f[s][i],f[t][i]+f[s^t][i]-1);
            }
        }
        SPFA(f[s]);
    }
    // 76 46 1 180 174

    int o=1e9;
    for(ri i=1;i<=n*m;++i)
        o=min(o,f[(1<<k)-1][i]);
    if(o==1e9||O<o) return;
    if(o<O) O=o,ans=1e9;
    int l=1,r=min(top,ans-1),mid;
    while(l<=r){
        mid=(l+r)>>1;
        memset(f,0x3f,sizeof(f));
        for(ri i=1;i<=n;++i){
            for(ri j=1;j<=m;++j){
                int u=id(i,j);
                if(a[i][j]<=mid) w[u]=255;
                else w[u]=257;
                if(~c[i][j])
                    f[1<<p[c[i][j]]][u]=w[u];
            }
        }
        for(ri i=1;i<=n*m;++i) g[i].clear();
        for(ri i=1;i<=n;++i){
            for(ri j=1;j<=m;++j){
                if(c[i][j]==-1) continue;
                for(ri l=0;l<4;++l){
                    int x=i+w1[l],y=j+w2[l];
                    if(x<1||x>n||y<1||y>m||c[x][y]==-1) continue;
                    int u=id(i,j),v=id(x,y);
                    g[u].push_back((edge){v,w[v]});
                }
            }
        }
        for(ri s=0;s<(1<<k);++s){
            for(ri t=s;t;t=(t-1)&s){
                for(ri i=1;i<=n*m;++i){
                    f[s][i]=min(f[s][i],f[t][i]+f[s^t][i]-w[i]);
                }
            }
            SPFA(f[s]);
        }
        int res=1e9;
        for(ri i=1;i<=n*m;++i)
            res=min(res,f[(1<<k)-1][i]);
        if(res<=(o<<8)){
            ans=mid;
            r=mid-1;
        }
        else l=mid+1;
    }
}
int main(){
    // freopen("chocolate1.in","r",stdin);
    // freopen("1.out","w",stdout);
    srand(time(0));
    for(ri t=read();t;--t){
        n=read(),m=read(),k=read();
        for(ri i=1;i<=n;++i){
            for(ri j=1;j<=m;++j){
                c[i][j]=read();
            }
        }
        for(ri i=1;i<=n;++i){
            for(ri j=1;j<=m;++j){
                a[i][j]=read();
            }
        }
        lsh();
        ans=1e9;
        O=1e9;
        for(ri s=1;s<=120;++s){
            for(ri i=1;i<=n*m;++i)
                p[i]=rand()%k;
            work();
        }
        if(ans==1e9) puts("-1 -1");
        else printf("%d %d\n",O,vec[ans]);
    }
    return 0;
}

杜老师

线性基+根号分治+结论

对于这种乘积为完全平方数的题,有一个线性基的套路。
对于一个数,根据它是质数 \(p_{i}\) 的奇偶次方来决定其第 \(i\) 位上是0还是1。
这样就变成了求线性基能够有多少种最后异或和为0的方案数。
答案就是 \(2^{n-|S|}\) ,其中 \(|S|\) 为线性基的元素个数。

这样,就有一个 \(O(\frac{P^2\sum n }{w})\) 的做法,其中 \(P\) 是质数个数,大概是可以拿30~50分的样子。
对它进一步优化,可以发现超过 \(\sqrt{n}\) 的质数至多出现一次,因此可以对超过 \(\sqrt{n}\) 的质数单独开线性基。
不超过 \(\sqrt{n}\) 的质数个数大约是450个。
此时复杂度优化到了 \(O(\frac{B^2\sum n}{w})\)
可以拿到至少 \(50\) 分。

看向部分分,可以发现有一个点是满足 \(r-l \geq 999990\) 的,可以发现在这种情况下区间 \([l,r]\) 中出现过的质数都是在线性基内的。
因此,这种情况下只需要统计区间 \([l,r]\) 中出现了多少种质数,即有多少质数 \(p\) 满足 \(\lfloor\frac{r}{p}\rfloor \not = \lfloor\frac{l-1}{p}\rfloor\)
这样就可以多获得 \(10\) 分。
这个结论可不可以拓展一下呢?
强行让这个结论得到的过程看起来合理
通过打表大法可以发现,当区间长度超过了 \(2\sqrt{n}\) 之后,都满足了上面这个规律。
因此,超过 \(2\sqrt{n}\) 的区间数质数个数,小于的则用线性基,时间复杂度 \(O(T\frac{\sqrt{n}B^2}{w})\) ,可以通过此题。

Code
#include<cstdio>
#include<bitset>
#include<map>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
const int MAXN=1e7+7;
const int B=450;
int prim[MAXN],flag[MAXN];
#define T bitset<B+10> 
const ll mod=998244353;
void getprim(int N=1e7){
    int &cnt=prim[0];
    for(ri i=2;i<=N;++i){
        if(!flag[i]) prim[++cnt]=i;
        for(ri j=1;j<=cnt&&prim[j]*i<=N;++j){
            flag[i*prim[j]]=1;
            if(!(i%prim[j])) break;
        }
    }
}
int top;
T f[7005],base[B];
int cnt;
void insert(T &x){
    for(ri i=B-1;~i;--i){
        if(x[i]){
            if(!base[i][i]){
                base[i]=x;
                return;
            }
            x^=base[i];
        }
    }
    ++cnt;
}
il ll ksm(ll d,ll t){
    ll res=1;
    for(;t;t>>=1,d=d*d%mod)
        if(t&1) res=res*d%mod;
    return res;
}
map<int,int> M;
int main(){
    // freopen("rand.in","r",stdin);
    // freopen("1.out","w",stdout);
    getprim();
    for(ri t=read();t;--t){
        ll l=read(),r=read();
        cnt=top=0;
        M.clear();
        if(r-l+1>=7000){
            cnt=r-l+1;
            for(ri i=1;i<=prim[0]&&prim[i]<=r;++i)
                if(r/prim[i]!=(l-1)/prim[i]) --cnt;
            print(ksm(2,cnt));
            continue;
        }
        for(ri i=0;i<=B;++i) base[i].reset();
        for(ri i=l;i<=r;++i){
            ll p=i;
            T x;
            x.reset();
            for(ri j=1;j<=B&&p!=1;++j){
                int d=0;
                while(p%prim[j]==0) p/=prim[j],d^=1;
                if(d) x[j-1]=1;
            }
            if(p!=1){ 
                if(!M.count(p)){
                    M[p]=++top;
                    f[top]=x;
                    continue;
                }
                x^=f[M[p]];
            }
            insert(x);
        }
        print(ksm(2,cnt));
    }
    return 0;
}

换桌

link
D1T3反而是D1里面最简单的
说好网络流不卡Dinic,费用流不卡EK呢
首先一眼费用流,每章桌子内部的每两个相邻点之间连一条费用为 \(1\) 的边,表示桌子内部的移动。
同时,每个点都向别的桌子对应的点连一条边,费用为 \(2dis(i,j)\)
然后源点向每个人连一条边,每个位置向汇点连一条边。

分析一下复杂度,大概有\(O(n^2m)\) 条边,由于使用了EK需要增广 \(O(nm)\) 次,每次增广要跑一次 SPFA ,所以总复杂度是 \(O(n^4m^3)\),看上去非常离谱。

但是这样可以拿到70分,估计是因为随机数据吧。
可以发现复杂度瓶颈在于桌子之间的连边,这种区间连边可以使用线段树优化建图,正反建两棵线段树。
边数优化到了 O(nm) 的级别,总复杂度也就优化到了 \(O(n^3m^3)\),再加上SPFA跑不满,以及一些奇怪的优化,勉强卡过了这题。
听说正解是zkw费用流?

Code
#include<cstdio>
#include<deque>
#include<cstring>
#include<vector>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
il ll abs(const ll &x){return x<0?-x:x;}
const int MAXM=1e6+7;
const int MAXN=1.5e4+7;
struct edge
{
    int u,w,c;
}e[MAXM];
const int B=20;
vector<int> g[MAXN];
int cnt=-1,s,t,n,m;
int pre[MAXN],from[MAXN];
char mark[MAXN];
void link(int u,int v,int w,int c){
    e[++cnt]=(edge){v,w,c};
    g[u].push_back(cnt);
    e[++cnt]=(edge){u,0,-c};
    g[v].push_back(cnt);
}
int dis[MAXN],lst;
bool SPFA(){
    memset(pre,-1,sizeof(pre));
    memset(from,-1,sizeof(from));
    memset(dis,0x3f,sizeof(dis));
    memset(mark,0,sizeof(mark));
    deque<int> q;
    q.push_back(s);
    mark[s]=1;
    dis[s]=0;
    while(!q.empty()){
        int u=q.front();q.pop_front();
        mark[u]=0;
        for(ri i=0;i<g[u].size();++i){
            edge now=e[g[u][i]];
            if(!now.w||dis[now.u]<=now.c+dis[u]) continue;
            dis[now.u]=now.c+dis[u],pre[now.u]=g[u][i],from[now.u]=u;
            if(!mark[now.u]) 
                mark[now.u]=1,
                q.empty()?q.push_front(now.u):(dis[now.u]<dis[q.front()]?q.push_front(now.u):q.push_back(now.u));
        }
        if(dis[t]==lst) break;
    }
    lst=dis[t];
    return ~pre[t];
}
int L[305][15],R[305][15];
#define mid (L+R>>1)
#define lc c[u][0]
#define rc c[u][1]
int root[30];
int id[MAXN];
int c[MAXN][2],Cnt,tot;
void build_1(int &u,int L,int R,int z){
    if(!u) u=++Cnt;
    if(L==R){
        id[u]=n*m+(L-1)*m+z;
        return;
    }
    id[u]=++tot;
    build_1(lc,L,mid,z);
    build_1(rc,mid+1,R,z);
    link(id[u],id[lc],1e9,0);
    link(id[u],id[rc],1e9,(mid+1-L)<<1);
}
void Link_1(int u,int l,int r,int pos,int x,int L=1,int R=n){
    if(l==L&&r==R){
        link(pos,id[u],1e9,l-x<<1);
        return;
    }
    if(r<=mid) Link_1(lc,l,r,pos,x,L,mid);
    else if(l>mid) Link_1(rc,l,r,pos,x,mid+1,R);
    else Link_1(lc,l,mid,pos,x,L,mid),Link_1(rc,mid+1,r,pos,x,mid+1,R);
}
void build_2(int &u,int L,int R,int z){
    if(!u) u=++Cnt;
    if(L==R){
        id[u]=n*m+(L-1)*m+z;
        return;
    }
    id[u]=++tot;
    build_2(lc,L,mid,z);
    build_2(rc,mid+1,R,z);
    link(id[u],id[lc],1e9,(R-mid)<<1);
    link(id[u],id[rc],1e9,0);
}
void Link_2(int u,int l,int r,int pos,int x,int L=1,int R=n){
    if(l==L&&r==R){
        link(pos,id[u],1e9,x-r<<1);
        return;
    }
    if(r<=mid) Link_2(lc,l,r,pos,x,L,mid);
    else if(l>mid) Link_2(rc,l,r,pos,x,mid+1,R);
    else Link_2(lc,l,mid,pos,x,L,mid),Link_2(rc,mid+1,r,pos,x,mid+1,R);
}
int main(){
    // freopen("15(1).in","r",stdin);
    n=read(),m=read();
    tot=2*n*m+1;
    s=MAXN-2,t=MAXN-1;
    for(ri i=0;i<n;++i){
        for(ri j=0;j<m;++j){
            int u=i*m+j;
            link(s,u,1,0);
            link(u+n*m,t,1,0);
            int l=i*m+(j+1)%m,r=i*m+(j-1+m)%m;
            link(u+n*m,l+n*m,1e9,1);
            link(u+n*m,r+n*m,1e9,1);//实现桌子内部的调整位置
        }
    }
    for(ri i=0;i<n;++i)
        for(ri j=0;j<m;++j)
            L[i][j]=read();
    for(ri i=0;i<n;++i)
        for(ri j=0;j<m;++j)
            R[i][j]=read();
    for(ri i=0;i<m;++i){
        build_1(root[i],1,n,i);
        build_2(root[m+i],1,n,i);
    }
    for(ri i=0;i<n;++i){
        for(ri j=0;j<m;++j){
            int u=i*m+j;
            // for(ri k=L[i][j];k<=R[i][j];++k){
            //     v=k*m+j;
            //     link(u,v+n*m,1,abs(i-k)<<1);
            // }
            if(R[i][j]>=i) Link_1(root[j],max(L[i][j]+1,i+1),R[i][j]+1,u,i+1);
            if(L[i][j]<i) Link_2(root[m+j],L[i][j]+1,min(R[i][j]+1,i),u,i+1);
        }
    }
    ll ans=0,res=0;
    while(SPFA()){
        ll cost=0,flow=1e18;
        for(ri u=t;u!=s;u=from[u]) 
            flow=min(flow,e[pre[u]].w);
        for(ri u=t;u!=s;u=from[u]) 
            e[pre[u]].w-=flow,e[pre[u]^1].w+=flow;
        ans+=flow,res+=flow*dis[t];
    }
    if(ans!=n*m) return !puts("no solution");
    print(res);
    return 0;
}

大魔法师

link
数据结构题,应该不难看出来是线段树。
稍微想想就能发现这个操作用矩阵维护起来会比较方便。
线段树上每一个点维护这样的一个向量

\[\begin{bmatrix} A\\ B\\ C\\ len\\ \end{bmatrix} \]

其中 \(len\) 表示的是区间长度。
再另外维护一个tag矩阵就好了,六种操作的矩阵都可以轻松构造出来。
剩下的就是码码码了。可能还要卡常

Code
#include<cstdio>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
const ll mod =998244353;
il ll add(ll x,ll y){return (x+=y)<mod?x:x-mod;}
namespace Matrix{
    const int M_MAXN=4;
    const ll lim=mod*mod;
    struct M
    {
        ll m[M_MAXN][M_MAXN]={},x,y;
        ll* operator[](const int &p){return m[p];}
        void reset(){
            for(ri i=0;i<x;++i)
                for(ri j=0;j<y;++j)
                    m[i][j]=0;
            for(ri i=0;i<x;++i) m[i][i]=1;
        }
    };
    M operator+(M a,M b){
        M c;
        c.x=a.x,c.y=b.y;
        c[0][0]=add(a[0][0],b[0][0]);
        c[1][0]=add(a[1][0],b[1][0]);
        c[2][0]=add(a[2][0],b[2][0]);
        c[3][0]=add(a[3][0],b[3][0]);
        return c;
    }
    M operator*(M a,M b){
        M c;
        c.x=a.x,c.y=b.y;
        for(ri i=0;i<c.x;++i){
            for(ri k=0;k<a.y;++k){
                for(ri j=0;j<c.y;++j){
                    c[i][j]=c[i][j]+a[i][k]*b[k][j];
                    if(c[i][j]>=lim) c[i][j]-=lim;
                }
            }
        }
        for(ri i=0;i<c.x;++i)
            for(ri j=0;j<c.y;++j)
                c[i][j]%=mod;
        return c;
    }
}
using namespace Matrix;
M tg[7];
void init(){
    for(ri i=1;i<=6;++i)tg[i].x=tg[i].y=4;
    tg[1][0][0]=tg[1][1][1]=tg[1][2][2]=tg[1][3][3]=tg[1][0][1]=1;
    tg[2][0][0]=tg[2][1][1]=tg[2][2][2]=tg[2][3][3]=tg[2][1][2]=1;
    tg[3][0][0]=tg[3][1][1]=tg[3][2][2]=tg[3][3][3]=tg[3][2][0]=1;
    tg[4][0][0]=tg[4][1][1]=tg[4][2][2]=tg[4][3][3]=1;
    tg[5]=tg[6]=tg[4];
}
M getmat(int typ,ll v=0){
    if(typ<=3) return tg[typ];
    M res=tg[typ];
    if(typ==4) res[0][3]=v;
    if(typ==5) res[1][1]=v;
    if(typ==6) res[2][2]=0,res[2][3]=v;
    return res;
}
const int MAXN=2.5e5+7;
struct node
{
    ll a,b,c;
}p[MAXN];
struct seg
{
    #define lc u<<1
    #define rc u<<1|1
    #define mid (t[u].l+t[u].r>>1)
    struct T
    {
        int l,r;
        int f;
        M w,tag;
    }t[MAXN<<2];
    void update(int u){t[u].w=t[lc].w+t[rc].w;}
    void pushdown(int u){
        if(t[u].f){
            t[u].f=0;
            t[lc].w=t[u].tag*t[lc].w,t[lc].tag=t[u].tag*t[lc].tag,t[lc].f=1;
            t[rc].w=t[u].tag*t[rc].w,t[rc].tag=t[u].tag*t[rc].tag,t[rc].f=1;
            t[u].tag.reset();
        }
    }
    void build(int u,int l,int r){
        t[u].l=l,t[u].r=r;
        t[u].tag.x=t[u].tag.y=4;
        t[u].tag.reset();
        if(l==r){
            t[u].w.x=4,t[u].w.y=1;
            t[u].w[0][0]=p[l].a;
            t[u].w[1][0]=p[l].b;
            t[u].w[2][0]=p[l].c;
            t[u].w[3][0]=1;
            return;
        }
        build(lc,l,mid);
        build(rc,mid+1,r);
        update(u);
    }
    void modify(int u,int l,int r,const M &tag){
        if(t[u].l==l&&t[u].r==r){
            t[u].f=1;
            t[u].tag=tag*t[u].tag;
            t[u].w=tag*t[u].w;
            return;
        }
        pushdown(u);
        if(r<=mid) modify(lc,l,r,tag);
        else if(l>mid) modify(rc,l,r,tag);
        else modify(lc,l,mid,tag),modify(rc,mid+1,r,tag);
        update(u);
    }
    il M query(int u,int l,int r){
        if(t[u].l==l&&t[u].r==r) return t[u].w;
        pushdown(u);
        if(r<=mid) return query(lc,l,r);
        else if(l>mid) return query(rc,l,r);
        else return query(lc,l,mid)+query(rc,mid+1,r);
    }
    #undef lc
    #undef rc
    #undef mid
}T;
int n,m;
int main(){
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    init();
    n=read();
    for(ri i=1;i<=n;++i) p[i].a=read(),p[i].b=read(),p[i].c=read();
    T.build(1,1,n);
    m=read();
    for(ri i=1;i<=m;++i){
        int typ=read(),l=read(),r=read();
        if(typ==7){
            M ans=T.query(1,l,r);
            printf("%lld %lld %lld\n",ans[0][0],ans[1][0],ans[2][0]);
        }
        else{
            ll v=0;
            if(typ>3) v=read();
            T.modify(1,l,r,getmat(typ,v));
        }
    }
    return 0;
}

如果奇迹有颜色

link
神仙题+2
更加离谱了。
先给出做法:Burnside+BM

根据Burnside定理,可以得到最后的答案是\(\sum^{}_{d|n}\varphi(\frac{n}{d})f_d\) ,其中 \(f_d\) 表示长度为 \(d\) 的满足条件的环的个数。
对于前面的 \(\varphi\) 有手就行,难点在于 \(f_d\) 上。
可以发现 \(m\) 比较小,因此可以想到一个一个状压dp, \(dp_{i,S}\) 表示已经转移了 \(i\) 次,最后 \(m\) 个颜色是 \(S\) 的方案数。
但是还要考虑这是个环。
因此,还需要枚举开头的颜色状态,并在最后得到的 \(dp_{n-m,S}\) 上check一下能否再加上开头的颜色。
这样可以得到一个 \(O(nm m^{2m})\) 的做法,把转移过程换成矩阵可以单次"优化"到 \(O(m^{4m} \log n)\)
上面这种做法的复杂度瓶颈在于枚举开头的颜色状态,这个过程比较浪费。

可以发现,对于一串开头的颜色状态,其长度为 \(m\) ,必然有一个位置 \(i\in[2,m]\) ,使得颜色 \(c_i\)\([1,i-1]\) 中出现过,不难发现这是充分必要的。
因此,可以枚举这个位置 \(i\),然后再枚举这个位置的颜色是 $c_{1 \dots i-1} $中的哪一个。
可以默认前面的 \(i-1\) 的颜色分别为 \(1 \dots i-1\) ,最后的方案数再乘上一个 \(( \matrix m\\i-1 ) \times (i-1)!\),表示从 \(m\) 个颜色中选取 \(i-1\) 个分配给前面的颜色,然后这 \(i-1\) 个颜色任意排列。
这样的复杂度就分别降至了 \(O(nm^3 m^m)\)\(O(m^2 m^{3m} \log n)\) ,期望得分已经到了50分左右了。

接下来该怎么优化?已经没啥可以优化的了,该考虑换种做法了。
对于 \(f\) ,我们大胆猜测它是一个线性递推式!为啥,我也不知道
而且,通过前面的dp来看,每经过 \(m^{m}\) 次转移,这个dp数组就会被刷新一次,即每个状态都会被枚举一次,因此其递推式的长度不会超过 \(m^m\)
然后暴力打表BM了
回到上面的不用矩阵的dp,它是可以顺便求出第1~\(n\) 项的,因此使用这个方法打出对于每一个 \(m\) 的表。
打多长的表呢?这得看你觉得你的RP如何了,我是选择打了前1500项。 如果递推式再长就连线性递推都跑不过去了
最后可以发现,当m=7的时候,最长的递推式也才只有409项,不过打了20多分钟才打出来。

打表程序
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
/*
f[i][s]表示当前长度为i,染色状态为s的时候的方案数  
具体做法就是设初始状态S为1,然后暴力转移  
最外层枚举S 的复杂度是 m^{m}  
然后枚举下一个颜色是什么,O(m)  
最外层一个n  
所以总复杂度是O(nm (m^m)^2) 的  
这个东西的复杂度瓶颈在于枚举开头的颜色  
空间上则可以使用滚动数组
*/
int n,m;
const int MAXN=1007,MAXM=1e6+7;
const ll mod=1e9+7;
il ll add(ll x,ll y){return (x+=y)<mod?x:x-mod;}
il ll dec(ll x,ll y){return (x-=y)<0?x+mod:x;}
ll tot;
ll ksm(ll d,ll t){
    ll res=1;
    for(;t;t>>=1,d=d*d%mod)
        if(t&1) res=res*d%mod;
    return res;
}
int nxt(int S,int x){
    return S*m%tot+x;
}
int a[16],mark[MAXM];
ll g[MAXM],cur[MAXM],f[MAXN];
ll fac[MAXN],ifac[MAXN];
void init(int n=MAXN-1){
    fac[0]=1;
    for(ri i=1;i<=n;++i) fac[i]=i*fac[i-1]%mod;
    ifac[n]=ksm(fac[n],mod-2);
    for(ri i=n-1;~i;--i) ifac[i]=ifac[i+1]*(i+1)%mod;
}
int main(){
    //freopen("rand.in","r",stdin);
    freopen("1.out","w",stdout);
    init();
    n=read(),m=read();
    tot=ksm(m,m);
    for(ri i=0;i<tot;++i){
        memset(a,0,sizeof(a));
        int x=i;
        for(ri j=0;j<m;++j){
            a[x%m]=1;
            x/=m;
        }
        for(ri j=0;j<m;++j){
            if(!a[j]){
                mark[i]=1;
                break;
            }
        }
    }
    for(ri l=1;l<m;++l){
        int s=0;
        for(ri i=1;i<=l;++i) s=s*m+i;
        for(ri k=1;k<=l;++k){
            for(ri i=0;i<tot;++i) g[i]=0;
            g[s*m+k]=1;
            for(ri i=1;i<=n-l-1;++i){
                for(ri j=0;j<tot;++j) cur[j]=0;
                for(ri j=0;j<tot;++j){
                    for(ri x=0;x<m;++x){
                        int t=(j*m+x)%tot;
                        if(mark[t]) cur[t]=add(cur[t],g[j]);
                    }
                }
                for(ri j=0;j<tot;++j) g[j]=cur[j];
                ll res=0;
                for(ri j=0;j<tot;++j){
                    int flag=1;
                    for(ri x=1,t=j;x<=l+1;t=t*m%tot+(x>l?k:x),++x){
                        if(!mark[t]){
                            flag=0;
                            break;
                        }
                    }
                    if(flag) 
                        res=add(res,g[j]);
                }
                res=res*fac[m]%mod*ifac[m-l]%mod;
                f[i+l+1]=add(f[i+l+1],res);
            }
        }
    }
    for(ri i=1;i<m;++i) f[i]=ksm(m,i);
    f[m]=dec(ksm(m,m),fac[m]);
    print(n);
    for(ri i=1;i<=n;++i) 
        printf("%lld,",f[i]);
    // for(ri i=0;i<tot;++i) print(mark[i]);
    return 0;
}

找递推式
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
const ll mod=1e9+7;
il ll dec(ll x,ll y) {return x>=y?x-y:x-y+mod;}
il ll add(ll x,ll y) {return x+y<mod?x+y:x+y-mod;}
ll ksm(ll d,ll t){
    ll res=1;
    for(;t;t>>=1){
        if(t&1) res=res*d%mod;
        d=d*d%mod;
    }
    return res;
}
const int MAXN=1e4+7;
namespace GetP{
    vector<ll> f[MAXN];
    ll d[MAXN],fail[MAXN],cnt;
    vector<ll> main(int n,ll *a){
        for(ri i=0;i<n;++i){
            d[i]=a[i];
            for(ri j=0;j<f[cnt].size();++j)
                d[i]=dec(d[i],f[cnt][j]*a[i-j-1]%mod);
            if(!d[i]) continue;
            fail[cnt]=i;
            if(!cnt){
                f[++cnt].resize(i+1);
                continue;
            }
            int id=cnt-1,w=i+f[id].size()-fail[id];
            for(ri j=0;j<cnt;++j)
                if(i+f[j].size()-fail[j]<w)
                    id=j,w=i+f[j].size()-fail[j];
            ll x=d[i]*ksm(d[fail[id]],mod-2)%mod;
            f[cnt+1]=f[cnt],++cnt;
            if(f[cnt].size()<w) f[cnt].resize(w);
            int delta=i-fail[id];
            f[cnt][delta-1]=add(f[cnt][delta-1],x);
            for(ri j=0;j<f[id].size();++j)
                f[cnt][j+delta]=dec(f[cnt][j+delta],f[id][j]*x%mod);
        }
        return f[cnt];
    }
}
ll n,k,m;
vector<ll> res;
ll a[MAXN];
int main(){
    freopen("1.out","r",stdin);
    freopen("2.out","w",stdout);
    n=read();
    for(ri i=0;i<n;++i) a[i]=read();
    res=GetP::main(n,a);
    k=res.size();
    print(k);
    printf("0");
    for(ri i=0;i<k;++i) printf(",%lld",res[i]);
    return 0;
}
最终代码
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
ll len[]={0,1,1,6,17,45,131,409};
ll r[][500]={
{0},
{0},
{1},
{2,2,1000000006,1000000005,1000000004,1000000006},
{4,1000000006,1,1000000005,999999999,999999990,999999993,2,999999998,18,23,5,7,0,0,1000000003,1000000003},
{5,1000000006,2,1,1000000001,999999950,999999888,999999861,999999766,999999929,999999707,370,837,1213,610,1171,1830,999999162,115,999999163,999998834,999994353,999999285,999997782,999997737,999998268,2503,373,999998305,3762,2619,1105,999998539,2919,999999711,999999835,68,1392,999999883,16,456,400,240,192,288},
{6,1000000005,12,999999994,5,999999957,999999559,999999080,999998217,999997548,999996344,47,999998073,33128,52072,136222,152972,91065,65733,999955386,999588063,998830398,998260811,998297012,999163243,994165080,991974669,996116576,2807363,13558353,997037534,39235886,85654940,110827506,41365815,978978435,93218224,164892618,13927038,562912533,771321300,965011201,835321352,634194048,889066230,953163650,878190764,460010303,684312041,548204853,608010979,179982084,227826961,818370526,451348385,803007399,693455486,378294261,924698432,944761643,270309071,873113915,793746856,200243807,322095256,87677704,319668500,783560924,790772175,369187864,140859227,349859658,631426585,782039070,67885082,835132718,49616680,282792562,330323164,732637271,230975002,116109196,886247018,765631897,269216721,862063652,639379219,936011210,173868589,241480135,398874422,874757826,960020433,203549148,842620787,195018181,963469382,913064622,716014212,741473025,75821683,159335840,482498289,559939158,314363448,51538938,778364348,8365497,879573490,920947292,124076643,144490645,422055922,736757760,347764750,695285774,80640505,268186105,474888192,616132608,326682624,297750528,990415367,72695808,845613575,857115143,862423559,891177479,946915847,31850496,63700992},
{8,999999998,13,0,999999999,999999982,999999857,999996451,999996527,999989816,999978096,999961987,999924280,38049,999880715,1419892,1951388,5311062,10505810,16094505,3079773,38047274,10512993,850038574,731469180,290700101,387128425,148700701,880065743,589043100,294428323,559638260,598110350,811717323,97319849,830367378,584618896,776691623,825929297,760332569,823286591,699894962,73156678,208357268,157936399,839472733,327841005,805906380,378539109,354236555,726318008,381078211,289670519,937027131,91131249,301195738,758453409,484029063,662080976,915059724,228533778,272443796,385406676,367676058,865362626,286356863,307716634,705946384,869856470,782551769,703904776,913061726,581684523,410565815,429055668,995576042,625436033,487258472,79577377,691334271,34431409,757114241,365702616,289855132,706750782,677303697,288449471,22984491,902833463,32438350,956868697,106596712,826432864,556738470,802459922,765703064,538174742,804366026,413751749,201243657,930602656,161180839,364387208,765534699,619102160,811114084,712595943,373541212,444090519,338490847,565516756,988037207,587536727,376379924,46912871,171418271,160880676,726875897,536814802,196688776,317779448,378179965,920764146,903221839,33745006,692994758,309230513,111378117,982551754,508615263,641061467,732010973,633819182,161090109,431557050,367896031,607736670,76792724,78024709,260044925,37660394,37699272,33669982,877200582,552270444,45539160,999206870,483462022,472989092,919008393,301714757,867933108,655807437,673998892,785908706,490103184,653321286,932970656,833009347,328557471,890304325,146069701,243806019,661234519,709306174,596691901,596574086,76111221,674491946,129147985,985039291,56065093,712732443,452891372,993735467,133311806,627679151,369274626,403945286,819656439,621218006,825237485,371207586,231351522,3863786,601943536,344856557,532015273,152091464,28304052,293554246,57610737,669644045,674033113,746169936,68143830,772903222,461732246,763727998,984383407,341128470,785459526,590057248,729449070,400745651,376358569,132475947,294976698,669397431,143696612,478385559,243303394,602119463,905737892,940257576,702100421,98759576,116429731,354024377,916258769,264684993,355325701,199663848,466482870,278800066,726955610,686110432,454862177,786057224,438797939,73664170,889393111,894637913,439677044,140024915,922335713,630701015,804179342,316758236,422074851,722400342,301280228,710748509,236538824,547905368,693075423,88595360,941816587,422014019,624811701,559836534,188611318,409680261,977881539,476278374,571923105,834856828,333802642,827857673,781562421,614327597,574525723,965705418,351249753,406957462,570105321,940854982,666773398,522225060,454154589,14597802,962633549,757248633,84847848,966028207,591657306,359099247,159502682,165475065,327917413,109367543,308856648,349986766,535443247,525926041,358398468,315756710,190547322,795198087,900278703,586278917,915109848,7052980,639415393,825087888,484935494,770450911,365046295,560386965,488931568,56635929,272273784,948842454,954205329,812157505,15991594,841340231,7286480,273752414,483193902,158892250,7862606,713316559,224827001,26879504,924612572,59295983,603643063,359533039,13688383,24679348,520115182,957634819,583447150,335423094,683506755,506622618,169719634,902851094,67624519,286852344,336283122,607248096,444042031,455562376,439032384,784730598,35295189,190031504,57266574,879952393,621138726,507972141,857972482,984923513,384274933,824873982,279746426,383000508,106351052,948070279,942680150,233788862,703859,977365116,262630972,98643161,734938302,241040988,872065807,943501556,132390074,506715988,160170953,24894995,331653026,70316093,457520627,565287670,468596777,235574131,369945261,933631851,825156568,671751466,876752121,809740298,224798781,136992441,541402150,709447269,967349664,97238580,1336196,350083444,203699288,348721381,654231007,390002436,88082424,307411696,467583589,552773501,915050490,12768499,183571639,606204253,823991371,182211557,598956578,247309301,890803007,629395507,652457145,651744399,324285685,597420699,103571403,827381002},
};
ll a[][1024]={
{},
{0},
{2},
{3,9,21,45,93,219},
{4,16,64,232,784,2656,9496,34840,127504,468616,1725640,6360016,23451952,86494984,319047424,176921489,341631812,16422272,85596531,971427713},
{5,25,125,625,3005,13825,63845,305185,1470365,7113505,34401845,166503745,806139365,903547204,903216119,542977028,323080384,933588563,245001466,217963321,20482429,724242719,945621102,251636219,797004759,919825210,822599660,349963818,500077473,334257929,415474473,765534864,75450659,751510611,940855832,454939307,857438052,269311339,868193738,636253284,543107901,444295312,393049096,550023504,269687722,415037856,160702893,983851846,876104646,484301180,472412264,968994800,380043137,167717021,42995301,983069050,671176971,624289170,330424964,61476901,45130647,226165816,446113672,354234637,565160207,545594530,984210595,232676505,40124991,355459187,949474415,422368151,104837259,849846993,875653792,197146016,889963925,540275550,430537803,634514368,572099317,789694139,563227379,679905738,442991152,320743182,979599664,35983656,863940343,809051192,134592745,760616225,604628555,259250251,318860304,962553330,274915486,881345057,74416543,477951251,391440771,126696970,476355018,862912079,226671308,816176300},
{6,36,216,1296,7776,45936,264816,1529856,9008496,53258976,315221616,866880649,55884899,483506201,876846267,552401777,463889233,455943071,293587581,319885589,238945474,722988084,926302994,76526212,838282896,222174451,851794981,287634868,296988385,956264019,12167659,256340194,473429329,543641180,873062713,32786593,707495558,807536573,561579222,404406847,879459863,843577830,280044553,475315352,650035834,550711406,779857452,314565255,301585581,934490973,833297068,244107807,61308453,429600225,623235754,475837300,682069321,757633788,241060300,556711079,851849284,873655308,513049896,528195130,590560762,216246798,922688268,960420558,558615981,573385682,667992786,562208852,15241170,878927836,147872407,366069032,758587486,356186164,992281671,786640941,822160174,104690831,300812911,799991003,665843811,830321018,368412359,162583625,889484458,329014549,133127099,79006269,787648593,44202476,789970658,158420892,371483335,394842506,567847649,782189325,14619420,900032482,349194688,353628784,349910365,122462951,776570303,685657759,595552668,516951572,893580695,225882152,48899614,601076710,545779687,245608708,585457303,896379716,308121822,482111785,102191533,654760125,114694544,656398661,846955008,701123312,96855058,695085508,861748887,225965815,346218943,754585662,254263001,83283429,702237861,782564988,884763773,114841239,434773045,928218488,4327297,513923986,545570998,138006589,760525721,892239096,950578511,592131399,790111529,59215362,950026603,215333959,570941138,293577780,303692737,627552517,37612647,934819233,825796973,343536720,728896940,870744572,921201185,911973685,260135303,940528324,920859488,580668012,617432375,24484419,564416898,152311700,505052363,513278853,165379605,798843148,275239716,341719660,357981971,948297437,115402920,534192423,82107452,518262805,220920490,205637014,198459996,168787628,80312684,133977811,302674860,91226821,18942832,33522940,678864532,982209002,61901125,682791241,427429026,805553184,335229685,886072906,466309551,751420348,497918557,356373516,69623006,131431845,428535561,957319611,826471496,361448577,309304337,109368080,72913812,244440483,507407610,321141392,395838285,999986593,909227432,341923279,759953902,490959374,204394432,140252500,182352078,415892282,437026271,104023096,661399339,240365829,590814250,733536023,311125043,187833855,595423253,8744249,831231883,765371001,823878399,422292921,804251259,852392914,123575179,484189133,486370517,414883365,148112350,236078298,867059835,529033495,108628028,391231173,304464292,646932790,76344894,737850276,387727189,295805505,68382074,731849881,573495804,850181497,87202701,349149440,467761464,59496677,334327187,269247252,617716458,803948544,199943134,720174629,236922907,172232746,6563384,999945987,211373991,724713308,436577976,511549628,182522982,307429306,328634460,994128562,400524077,794062600,338964715,288750417,241606313,610438937,299576509,864358880,56091403,452952748,842937609,11727542,832030403,733639893,265885379,120190798,869754609,24978317,876379627,874669572,265954272,70644047,584160445,276842115,761753911,267096942,36400674,94457786,591815878,14095307,814115858,685315284,668999265,784753644,297668503,818050703,804556434,84609840,366928077,217778971,152807360,320864403,413536550,778677631,722454681,120930751,587324457,528256072,200553641,918162287,218573633,568395193,972548076,607716947,446896244,883463244,793470067,3575704,600504805,634650744,788435331,831903891,893833365,56585096,156494673,369183516,856453412,786564380,32048409,759414743,399546209,549565718,434735256,155705447,708570560,606503203,17268841,829106241,426378313,963909998,803091631,867460068,160211277,484784627,158271327,781766016,622188939,482527717,25478784,347542629,328603304,169239371,960877141,37138480,681258356,704480393,72548181,189259687,840832234,420485522,928991047,345360856,70310695,182869744,666628754,120045847,746946112,712109935,466644486,157340625,587465153,87177336,569012281,960575934,897128633,473596677,915833636,719888745,555983212,338758980,468450987,843306763,956410664,379948555,657370229,738050330,160146554,292635163,186350783,274746357,893145265,778212536,459836213,274287548,379589366,634969102,508270887,356133635,520759140,508424536,620463873,724443922,526531928,525851204,677966115,295633701,120428181,108841951,208200228,749527976,789985645,495006253,722881209,542990192,756315492,866974279,779420375,848658178,515105043,719407759,556439406,221264174,69727954,235324763,613381347,346349966,874569756,95250918,732740880,871761456,222789585,391936606,379909732,406908324,508758593,942901782,125973735,28502060,174991438,967152166,686690802,393260406,655902821,204650143,696978912,878746354,790733051,402636798,94874128,72930826,978950379,552197916,309965797,663288419,241424350,938438744,726427374,536043927,230327444,867894194,82248411,8381358,640009821,687839977,722334032,62710799,235227277,983797049,931828110,144781998,101006856,759867712,17845829,925386863,656937184,644194134,171438244,49400323,678521440,175509372,644023610,969015620,885058786,859198971,472012114,775145327,292141172,614091268,349541618,452670297,803779724,831745289,693625024,985395183,953023632,387808179,277493352,314141395,783673832,947371702,767027522,780891321,812021240,561414225,278836887,541920843,478665257,161023753,331523491,75895569,846222723,626555818,53630559,639958893,442752306,492363015,87409420,821073455,526575431,279605761,571904738,503847329,400647029,893987194,607904276,755389693,901613183,276536339,741328412,965201339,178207366,673201038,395173456,900601505,390904578,693922712,329179388,656374528,210103562,581857757,507337857,836807206,513637971,111712607,685844742,978123037,422328949,187953352,234248187,168800635,276498111,780051279,357356221,96095400,101133251,35034156,83818244,664733846,567132865,736429769,484005383,261114951,128735170,263557817,213153411,314389905,372836488,307039173,132526244,185773740,531286287,135743364,701564274,884210550,909881917,527933635,699603932,132577812,278486955,489778165,525724754,884823686,609038219,382824254,368029743,809973619,145513794,170310346,65054829,155213354,29132504,463848138,770549486,330908806,941929428,961774575,183734511,175369794,284719130,993410020,707675923,143985172,881135731,340422433,333460086,886242270,576968441,842881547,640356923,888749394,141638361,895127578,957478532,846081531,486235484,516571783,16129749,611815393,200509562,578892490,318049351,566188274,635123453,570323562,518653036,300081252,282301776,638550283,303488731,984577082,351359382,375753873,859590813,896955980,875014533,759923926,461319864,939953785,172000430,431109968,78481776,75362265,247993328,168300321,877092976,991319017,129342331,186232030,422415006,308388813,842504154,856987382,934418346,624338789,302442326,342497954,947239708,477939076,259426430,962933619,598985913,129894091,448514554,545550992,623243797,277029583,912389637,432132350,278936826,417658879,959621438,410443031,494931183,227598772,49745399,829024229,367271890,825488430,697565369,507897188,782844448,51408812,146445008,124137991,221106270,238215317,558821615,611748281,748471802,630134476,231826890,618582064,923554488,602613593,528845978,897318105,445069557,280408051,167521808,213340528,529502296,681837113,847889305,667403139,370499408,364393665,883181374,943351286,159176082,833655938,143570960,402069717,229577574,895557913,888749687,408252719,808068992,474314906,504964733,320019371,924652218,377057680,123413679,270379770,509207221,843225076,681514576,196575352,440551843,366168944,713604055,762019426,878325482,453278197,48751252,868382014,338600187,401724566,660920837,66844323,521376278,2454932,966972086,388394624,248310217,719289432,658859051,253432998,530939855,622278176,517805199,642203508,446378915,989257350,981941160,178852959,394799068,575547498,120973479,197581561,377836615,770455580,680616894,610500118,118411057,364013850,822919269,807385336,809459927,212743196,313641614,816884699,977374504,294818405,259653408,125464780,482063521,662151667,399390866,780698634,437943172,180553724,601913547,630873215,748673949,61232014,978038390,495951005,201091089,154337568,22356416,323515174,720199524,646177763,27858173,176399985,985833037,919610326,346178191,891157247,214920843,95249148,375157550,188893164,873805162,428471118,330789302,473989296,52909927,234510041,667411177,29675760,16070412,300224561,718585277,345673587,740220157,869132123,271369269,935297446,708794962,118205706,357249487,815703593,266650190,290898962,521128398,970169576,971838794,158658885,687787524,990464643,144217336,45903932,48979925,685225768,674664524,348174157,658863350,289413518,587576816,641814209,155373363,171265180,143170580,618465872,495105516,800116924,496743834,605891566,569390129,994434666,822962582,290203596,224592670,30498276,709163477,617430076,656050217,437308456,937669211,910572509,902179773,547280726,154726407,18986848,44293587,146664597,40558574,912456369,737663584,356677117,257019875,100851916,323245232,688279089,953455630,604061563,590567548,414935262,261869637,819764876,553330978,106377592,985660807,657957820,811486134,179387562,605811309,149491099,995694132,957119812,616749796,10822704,211225639,767416818,963777326,466074087,637404640,8102445,899950752,154203014,977384809,866676705,536271331,900290871,758712734,392770842,746738086,889035159,171073150,953675819,484220799,140563810,914863675,134578578,835043836,634090883,215479007,76640086,726396782,491000730,443532861,107801638,793996322,735060797,351044935,889208817,352402133,621183623,153490276,230355854,872435510,210510626,127397470,808151428,244108108,893259446,233253078,670475892,419820703,450516304,754329304,44423734,734960558,507250975,186782247,38043098,416785081,112436215,233633604,369414113,187316132,989974477,497995907,237008688,624885225,747915533,993553561,670139082,532556241,568010193,563260261,429790374,874530216,726014817,46228866,262786143,378818216,753410855,497902893,938809495,738701263,576425029},
{7,49,343,2401,16807,117649,818503,5623681,38675287,268615249,869163296,13073990,611079937,993727399,53913585,640590288,868994356,401217177,254756223,480098846,543138002,966380710,742573033,362519843,14675419,487759357,999300341,833915923,314279646,6871396,844009879,765135375,5875334,11775247,13254195,443841515,654552976,938100748,495998091,615333989,284801544,173555787,540951599,234678025,155357689,595288264,761964999,286627266,119533964,837722689,186644491,768348482,702399639,902708395,311583988,472053092,488118378,233803480,793498577,21584398,617854772,261594300,44867240,598998392,477383380,987976117,717981890,187315096,943432647,310371315,804518701,728298955,450927185,318998737,565214210,878481742,949128795,540309348,858480488,352338762,317208298,563049179,735103787,104102872,976638927,797667282,11229945,987239774,872927299,124183924,360870141,865114405,56253386,177277900,88874714,448942389,432839679,953200468,511073178,353208082,271882848,969672163,25363253,70937824,486688581,404477043,767350676,170673185,226452599,736382777,45513369,488703036,13587194,265188940,323551564,392544388,329179264,6885974,598505332,481798793,295835537,69062220,899895359,198163752,518782060,935011494,404818589,112566998,556695188,634378478,732676352,133564137,25798960,193298356,855713307,204322908,381244187,99958364,645214603,854968698,761606044,174031106,580375576,375096267,4042802,398792982,182009096,712526812,701765145,529181804,898317429,218906966,719999194,931622922,668224987,780444040,230502621,228609449,870103393,674777650,793626437,648050578,907175631,931406075,240459924,218092788,547053156,634626038,717023446,661807111,829708357,658291434,586332674,512966939,762728931,694141692,967028920,427782731,633092410,376050359,183920564,781817233,413836967,307910709,903776010,735892798,360738914,678174213,679236172,230878321,403079653,18665482,125768823,239596958,864116374,97967758,164383767,629900360,638196789,923141603,136701840,214754547,358587833,829751999,328923797,353441076,380213483,26282303,297254335,5868613,2804722,387059151,789502274,185565536,216434038,273338784,37460503,511760986,93984652,908874622,421282496,444170090,884470432,755614212,142516228,504636462,396195545,286125142,7933538,203866982,222528724,584452396,838102232,919259323,827747738,798228747,984871279,83323932,614553409,317188959,599453658,366214896,405655596,544339391,762380748,264990881,553190122,745310410,832579306,867339092,915374156,834066649,955025438,429394766,387272357,167262517,759376675,597491451,904484914,363960933,633469979,869045398,218247070,677542228,266463992,628781904,352670081,920327926,739102297,722297776,769735973,871216671,179144317,369182406,133076429,758782403,614749959,23126417,611193412,263102922,357226773,643396416,664733439,387347124,952287997,953921137,31902287,440032754,519994385,699983461,604314455,477818433,133088502,776998234,37046088,716909887,919953839,746467362,470875753,704813293,236350668,137391472,781319293,557397018,258605993,825603130,633770264,120219964,161242140,770294083,968912055,769043077,914989461,742475560,791199780,597705298,143948906,711016349,813204420,334480714,70916094,593569258,151201476,734489825,53821683,934472370,750372726,109007291,91897246,629348234,95787596,267174621,745263041,833585806,629335411,342403342,514257657,749404347,403376794,879173901,477788834,267084133,692055821,525193066,432645307,984143871,244269129,993654927,641511135,815706911,67968059,565386750,494889725,247428568,327446664,293181787,267657704,208008750,276832000,230134734,714521077,83640043,566428115,29535296,145354444,666381926,992112333,303250442,300769344,558219753,628526301,195453048,873328727,999488508,119127320,823973672,385145810,95322745,595040901,760705507,791213328,760567385,494253974,742897137,412440299,962990851,832096729,825444941,288642346,665228848,692776352,73363926,184777238,909283670,930479128,275322065,247158237,792801839,2410000,701281960,778213070,826204767,526184552,257228538,782169419,718587159,914504970,639124015,163863493,884038656,504826951,860071021,309959975,38347352,854746839,634606311,884241458,232316996,983200937,891492380,344290847,77481841,907522128,109619467,70397465,855069906,598719426,956990300,118253680,572368217,72442343,407001605,61725142,219572643,818360059,874558766,420027273,269721981,662588904,295926395,441380516,455798575,525716288,814167938,517070940,101572240,768247011,64990242,429353707,758851458,365415733,63353856,604083981,434063953,238407692,835804407,435878084,813677691,15558888,313755891,993890434,556444135,935504183,445164547,921416833,917311543,305154996,876267739,687953473,911664477,276402182,611310944,429065570,882095163,581939526,130983922,74623550,104428723,860052550,587003273,940816882,331076967,712614144,323015763,217788746,628500179,95837865,674274020,465299869,456797181,719556811,217508845,116704753,256760539,565652063,698487345,326604509,339052721,452756741,925265050,384769366,916680653,84273659,199127790,75349084,203015140,957805373,448206214,262495534,831882953,863191071,784277439,961172493,967082205,35052118,212677337,109016816,771473153,692518049,491290797,457001111,180638852,908776752,575308408,552289897,981945415,301688301,893651695,443611357,45695652,787643939,655203707,823125725,375936115,480154625,827273254,781986460,541938441,37572991,941841991,698344135,659078514,428070727,660440618,470430926,813254157,294014266,804983235,850966425,160966510,984124639,755380420,145327907,243973607,145362937,771942256,847262344,988135631,156684600,95907432,908543169,905363458,719744334,811521121,324035062,874147282,1465603,618284912,445236657,720789153,513501751,341159373,140138314,541805397,453420651,320744071,505096342,94309105,807420560,800181653,819022152,973141258,491372156,355861997,581583764,721540902,494636456,331219251,953416932,74262439,101959789,570706319,266346924,950315396,926931644,868762916,515808888,192974944,708626232,771189883,821874508,585876161,634713126,534804776,785707160,785189389,641703212,64534607,775830815,859375261,896368177,894509449,982895522,825503388,689650461,318669343,28435429,834670404,529501491,536213735,448405683,877347124,430112194,716075911,720695600,974864583,627736496,784288817,897877159,622704306,965990627,243871396,567354932,391044921,392501721,868019920,483910326,93178245,237390332,707642737,974345266,220724362,886730626,669871365,286698683,544974147,432056417,505656733,920595551,334242238,622910271,361875136,776855658,34108791,13554819,526351331,708122408,471374160,916175358,572601309,616132061,111940766,287789203,929105083,898004199,715005783,5011234,251270289,795341977,512697251,685815063,122175000,432084140,351293147,50321005,537630198,521365037,565166790,998506174,599976964,356120562,251697559,922209633,50946539,691431108,469040239,791709521,901731696,62203853,61720794,783354165,801175155,685565080,721508507,561458386,426205881,99821790,236660741,552810124,482747934,813085718,337719844,143737357,164607139,325719238,465064843,365548771,320137441,729467701,557107928,96657256,751484922,715922174,63382182,667337721,23254825,298369593,770817270,474670255,315813323,479477445,760613328,412291648,447402298,908307469,252899232,500497734,585664578,407137399,623235153,969295735,150242298,387994081,565533089,216774852,20802303,244901970,128567852,994408602,914752745,789611458,838982607,173671459,60952943,509517803,246241248,507129663,301770571,756079512,53760705,707937766,329996788,642122386,339910281,944317505,171491994,424352209,786098411,498444100,449433235,417002277,636702824,398470255,873046321,288677382,192234880,485180841,951084340,667751172,433130514,581772537,882330942,893260669,757824951,799618313,391896200,760707456,306306925,219289633,230264461,765390776,752821824,689347238,715963437,519618472,175823110,549523642,631366629,274943597,611254882,673754986,219392935,33622979,692445481,73519899,723465773,227129639,690478335,539601836,14257938,116597352,507623919,370145417,198940614,254504559,3051321,630572127,132253970,525465336,510748222,208755076,429126646,317081050,565952514,858954792,220701546,789982579,679333856,835993588,908108052,83432887,997838712,76880135,752903152,954845099,71532273,100887663,119360162,510771288,185201807,971654817,711254509,628973616,5866765,27601812,394425028,388746544,309710008,227796094,739335192,823670203,734229447,620169205,398318695,443947189,851252283,941263639,912330096,227562692,813059077,409528677,513130076,371453208,372505334,744644916,523485418,116397963,873126306,479734481,220176352,538871615,16955402,5300404,68280674,927904380,95355245,407678313,891212039,956614619,275766830,156987640,272070191,212699676,672209895,407573086,688222671,83321735,150777084,610353,302808282,488823560,66761394,314435472,616539264,570167937,409611074,432461009,458437576,10430010,473666970,243122471,67361471,130858591,817915033,180770105,485388636,804333527,423609225,184956147,484352738,97426104,611334858,604617885,369461637,195548363,12073676,423668123,638957507,247513929,580849571,632670478,17359851,928067982,880375013,877988692,97073268,640444,202765381,386978645,456900132,18359292,468484526,127728769,140591097,696022006,96819132,578244181,311153197,509217567,485575347,688438856,781473088,389275273,272302539,699928222,31407625,573742253,58153620,724747928,841414289,34900225,929966167,732167117,389317452,526445539,797991304,138489830,399503765,74772980,127361172,505686544,242553876,690174324,975996786,391318776,293097661,287721237,537010775,90922266,456475536,810808005,882250232,933127955,504990650,213224778,50003397,95233964,508053195,950693507,26626488,837295703,972557561,546746439,122862544,817301243,120233817,891778514,105759935,593122136,580312716,546235623,973419695,311335688,203284752,652986323,664629007,788311330,318365547,287693815,242690700,954480542,12584853,736980722,824539901,315914912,1441853,151903866,969759650,314081832,283589078},
};
const ll mod=1e9+7;
il ll add(ll x,ll y){return (x+=y)<mod?x:x-mod;}
il ll dec(ll x,ll y){return (x-=y)<0?x+mod:x;}
il ll ksm(ll d,ll t){
    ll res=1;
    for(;t;t>>=1,d=d*d%mod)
        if(t&1) res=res*d%mod;
    return res;
}
namespace getf{
    const int MAXN=1e5+7;
    ll m_f[MAXN];
    void mul(int n,ll *f,int m,ll *g){
        for(ri i=0;i<=n+m;++i) m_f[i]=0;
        for(ri i=0;i<=n;++i){
            if(!f[i]) continue;
            ll *p=m_f+i,*q=g;
            for(ri j=0;j<=m;++j,++p,++q){
                *p=add(*p,f[i]*(*q)%mod);
            }
        }
        for(ri i=n+m;~i;--i) f[i]=m_f[i];
    }
    void Mod(int n,ll *f,int m,ll *g){
        for(ri i=n;i>=m;--i){
            if(f[i]){
                ll x=f[i]*ksm(g[m],mod-2);
                for(ri j=0;j<=m;++j){
                    f[i-j]=dec(f[i-j],g[m-j]*x%mod);
                }
            }
        }
    }
    ll f[MAXN],g[MAXN],h[MAXN];
    ll solve(int t,int m){
        t--;
        if(t<len[m]) return a[m][t];
        for(ri i=0;i<=len[m];++i) h[i]=f[i]=g[i]=0;
        for(ri i=0;i<len[m];++i) h[len[m]-i-1]=mod-r[m][i];
        h[len[m]]=1;
        f[0]=1,g[1]=1;
        Mod(1,g,len[m],h);
        for(;t;t>>=1){
            if(t&1){
                mul(len[m]-1,f,len[m]-1,g);
                Mod(2*len[m]-1,f,len[m],h);
            }
            mul(len[m]-1,g,len[m]-1,g);
            Mod(2*len[m]-1,g,len[m],h);
        }
        ll ans=0;
        for(ri i=0;i<len[m];++i) 
            ans=add(ans,a[m][i]*f[i]%mod);
        return ans;
    }
}
const int N=1e6+7;
ll phi[N],prim[N];
bool flag[N];
void getphi(int n=1e6){
    phi[1]=1;
    for(ri i=2;i<=n;++i){
        if(!flag[i]){
            prim[++prim[0]]=i;
            phi[i]=i-1;
            flag[i]=false;
        }
        for(ri j=1;j<=prim[0]&&prim[j]*i<=n;++j){
            flag[i*prim[j]]=1;
            if(!(i%prim[j])){
                phi[i*prim[j]]=phi[i]*prim[j];
                break;
            }
            phi[i*prim[j]]=phi[i]*(prim[j]-1);
        }
    }
}
ll Phi(ll x){
    if(x<=1e6) return phi[x];
    ll res=1;
    for(ri j=2;j*j<=x;++j){
        if(x%j==0){
            while(x%j==0){
                res*=j;
                x/=j;
            }
            res=res/j*(j-1);
        }
        if(x<=1e6) return res*phi[x];
    }
    if(x==1) return res;
    return res*(x-1);
}
ll n,m,ans;
int main(){
    getphi();
    n=read(),m=read();
    for(ri i=1;i*i<=n;++i){
        if(n%i) continue;
        ans=add(ans,Phi(i)*getf::solve(n/i,m)%mod);
        if(i*i!=n) ans=add(ans,Phi(n/i)*getf::solve(i,m)%mod);
    }
    print(ans*ksm(n,mod-2)%mod);
    return 0;
}

宇宙广播

\(k\) 维球体的公切面,做个锤子!
咕了

posted @ 2021-04-29 16:13  krimson  阅读(412)  评论(6编辑  收藏  举报