省选模拟24
A. 排队
设 表示前 个人有 个刺头的方案数
那么转移长这样
第一种是直接放在原来的刺头旁边把他替换掉
第二种是放在其他地方成为一个新刺头
发现模数以及 都很小
于是可以处理一下前模数个的转移,整个数组表示哪个位置对哪个位置的贡献系数
然后再倍增处理一下相同的,最后剩下的暴力转移
Code
#include<bits/stdc++.h>
#define int long long//OVERFLOW !!! MEMORY LIMIT !!!
#define rint signed
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int n,m,mod;
int a[1010][12][12];
int base[12][12],res[12],tmp[12][12];
inline void qpow(int k){
for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) base[i][j]=a[mod][i][j];res[0]=1;
while(k){
if(k&1){
for(int i=0;i<=m;i++) tmp[0][i]=res[i];
for(int i=0;i<=m;i++) res[i]=0;
for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) (res[j]+=tmp[0][i]*base[i][j])%=mod;
}
for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) tmp[i][j]=base[i][j];
for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) base[i][j]=0;
for(int i=0;i<=m;i++) for(int K=i;K<=m;K++) for(int j=K;j<=m;j++)
(base[i][j]+=tmp[i][K]*tmp[K][j])%=mod;
k>>=1;
}
}
signed main(){
#ifdef LOCAL
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
freopen("queue.in","r",stdin);
freopen("queue.out","w",stdout);
n=read(),m=read(),mod=read();
for(int i=0;i<=m;i++) a[0][i][i]=1;
for(int k=1;k<=mod;k++){
for(int i=0;i<=m;i++) for(int j=0;j<=m;j++){
a[k][i][j]+=a[k-1][i][j]*2*j;
a[k][i][j+1]+=a[k-1][i][j]*(k-2*j);
}
for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) a[k][i][j]%=mod;
}
qpow(n/mod);
int lim=n%mod;
for(int i=0;i<=m;i++) tmp[0][i]=res[i];
for(int i=0;i<=m;i++) res[i]=0;
for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) (res[j]+=tmp[0][i]*a[lim][i][j])%=mod;
printf("%lld\n",res[m]);
return 0;
}
B. 昵称
数位 设 表示考虑到第 位,前面匹配到了 上的 这个位置,然后是否包含完整的串,是否有前导零的方案数
然后用方案数求方案就行
Code
#include<bits/stdc++.h>
#define int long long//OVERFLOW !!! MEMORY LIMIT !!!
#define rint signed
#define meow(args...) fprintf(stderr,args)
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int n,N;
int kmp[1010],ans[1030];
map<bool,int>f[1030][1010][2];
char st[1010];
int dfs(int x,int y,bool v1,bool v2){
if(f[x][y][v1].find(v2)!=f[x][y][v1].end()) return f[x][y][v1][v2];
if(!x) return f[x][y][v1][v2]=v1;
int res=0,tmp;
for(int i=0,ty,tv1,tv2;i<=9;i++){
ty=y;tv2=v2|(i!=0);
if(tv2){
while(ty&&st[ty+1]!=(i+'0')) ty=kmp[ty];
if(st[ty+1]==(i+'0')) ty++;
}
tv1=v1|(ty==n);
tmp=dfs(x-1,ty,tv1,tv2);if(tv2) res+=tmp;
}
return f[x][y][v1][v2]=res;
}
void print(int x,int y,bool v1,bool v2,int K){
if(!x) return ;
for(int i=v2,ty,tv1;i<=9;i++){
ty=y;
while(ty&&st[ty+1]!=(i+'0')) ty=kmp[ty];
if(st[ty+1]==(i+'0')) ty++;
tv1=v1|(ty==n);
if(K<=f[x-1][ty][tv1][1]){
ans[x]=i;print(x-1,ty,tv1,0,K);
break;
}else K-=f[x-1][ty][tv1][1];
}
}
signed main(){
#ifdef LOCAL
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
freopen("nickname.in","r",stdin);
freopen("nickname.out","w",stdout);
scanf("%s",st+1);n=strlen(st+1);N=read();
for(int i=2,j=0;i<=n;i++){
while(j&&st[j+1]!=st[i]) j=kmp[j];
if(st[i]==st[j+1]) j++;
kmp[i]=j;
}
dfs(n+17,0,0,0);
for(int i=n;;i++){
if(N<=f[i][0][0][0]){
print(i,0,0,1,N);
for(int j=i;j;j--) putchar(ans[j]+'0');
break;
}else N-=f[i][0][0][0];
}
return 0;
}
C. 帝国防卫
对每个深度开一个线段树用来维护还差多少能比 大
用 序暴力跳父亲再暴力枚举深度修改区间,顺便维护最小值
如果最小值小于等于 了,就递归下去,直到单点,再用个树状数组去维护个数
复杂度
Code
#include<bits/stdc++.h>
#define int long long//OVERFLOW !!! MEMORY LIMIT !!!
#define lson st[x].ls
#define rson st[x].rs
#define rint signed
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int n,m,mxd;
int rt[100010],cnt;
int c[100010],a[100010],b[100010];
int head[100010],ver[200010],to[200010],tot;
int fa[100010],dfn[100010],siz[100010],dep[100010],clo;
inline void add(int x,int y){ver[++tot]=y;to[tot]=head[x];head[x]=tot;}
int BIT[100010];
struct seg{int mn,atag,ls,rs;}st[100010*20];
inline void ins(int x){for(;x<=n;x+=x&-x) BIT[x]++;}
inline int query(int x){if(!x) return 0;int res=0;for(;x;x-=x&-x) res+=BIT[x];return res;}
inline int ask(int l,int r){return query(r)-query(l-1);}
inline void pushup(int x){
st[x].mn=inf;
if(lson) st[x].mn=min(st[lson].mn,st[x].mn);
if(rson) st[x].mn=min(st[rson].mn,st[x].mn);
}
inline void pushdown(int x){
if(st[x].atag){
if(lson) st[lson].atag+=st[x].atag,st[lson].mn+=st[x].atag;
if(rson) st[rson].atag+=st[x].atag,st[rson].mn+=st[x].atag;
st[x].atag=0;
}
}
void ins(int &x,int l,int r,int pos,int k){
if(!x) x=++cnt;if(l==r) return st[x].mn=k,void();
int mid=(l+r)>>1;
if(pos<=mid) ins(lson,l,mid,pos,k);
else ins(rson,mid+1,r,pos,k);
pushup(x);
}
void upd(int x,int l,int r,int L,int R,int k){
if(!x) return ;
if(L<=l&&r<=R) return st[x].mn+=k,st[x].atag+=k,void();
int mid=(l+r)>>1;pushdown(x);
if(L<=mid) upd(lson,l,mid,L,R,k);
if(R>mid) upd(rson,mid+1,r,L,R,k);
pushup(x);
}
void chg(int x,int l,int r){
if(l==r) return st[x].mn=inf,ins(l),void();
int mid=(l+r)>>1;pushdown(x);
if(lson&&st[lson].mn<=0) chg(lson,l,mid);
if(rson&&st[rson].mn<=0) chg(rson,mid+1,r);
pushup(x);
}
void dfs(int x,int fa){
dfn[x]=++clo,siz[x]=1;dep[x]=dep[fa]+1;::fa[x]=fa;mxd=max(mxd,dep[x]);
for(int i=head[x];i;i=to[i]){
int y=ver[i];if(y==fa) continue;
dfs(y,x);siz[x]+=siz[y];
}
}
void down(int x,int k,int L,int R){
if(!k||!x) return ;int now=k,depx=dep[x];
while(now&&depx<=mxd){
if(!L){
upd(rt[depx],1,n,dfn[x],dfn[x]+siz[x]-1,-now);
}else{
if(dfn[x]<=L-1) upd(rt[depx],1,n,dfn[x],L-1,-now);
if(R+1<=dfn[x]+siz[x]-1) upd(rt[depx],1,n,R+1,dfn[x]+siz[x]-1,-now);
}
now/=2,depx++;
}
down(fa[x],k/2,dfn[x],dfn[x]+siz[x]-1);
}
signed main(){
#ifdef LOCAL
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
freopen("empire.in","r",stdin);
freopen("empire.out","w",stdout);
n=read();for(int i=1;i<=n;i++) c[i]=read();
for(int i=1,x,y;i<n;i++){x=read(),y=read();add(x,y),add(y,x);}
dfs(1,0);
for(int i=1;i<=n;i++) ins(rt[dep[i]],1,n,dfn[i],c[i]);
m=read();
for(int i=1,op,x,k;i<=m;i++){
op=read(),x=read();
if(op==1){
k=read();down(x,k,0,0);
for(int i=0;i<=20;i++) if(dep[x]+i<=mxd) chg(rt[dep[x]+i],1,n);
for(int i=0;i<=20;i++) if(dep[x]-i>=1) chg(rt[dep[x]-i],1,n);
}else printf("%lld\n",ask(dfn[x],dfn[x]+siz[x]-1));
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具