省流:\(100 + 100 + 100 + 5\)。
T1
题意:给一个括号序列 \(s\),求出长度最小的 \(s\) 的子序列 \(t\),满足 \(t\) 是合法括号序列且删掉 \(t\) 后 \(s\) 是一个特殊的序列。定义特殊的序列为长度 \(2n\),前 \(n\) 个都是 (
,后 \(n\) 个都是 )
。
\(n \leq 3 \times 10^6\)。
可以枚举特殊序列左右括号的分界点,有个比较显然的贪心就是往左一个一个加入左括号看合不合法,往右一个一个加入右括号看合不合法。这具有单调性,所以可以双指针。
代码:
T2
原题:AT_cf17_final_g。
最优策略:每次选取第⼀个 \(a_i = i\) 的位置,然后操作,这样不会破坏已经可以操作的位置的性质,同时可以尽可能多地操作。
分析发现,每次操作会把整个序列的总和 \(-1\)。所以可以考虑计算出所有不同初始值下 \(-i\) 的方案数总和。本质上就是计算出了所有情况下减去的总和。再用所有方案数的总和减去这个方案数就得到最终所有情况的答案。
而每个点只会被后⾯的点操作,于是我们倒着 dp,记 \(dp_{i,j}\) 表示到了第 \(i\) 位,它后面的位置总共对它造成了 \(j\) 次 \(+1\) 的操作”的方案数,然后我们枚举第 \(i\) 位的初始值 \(x\),如果可以操作那么⼀定可以在 \(i\) 处操作了 \(\lfloor \frac{x + j}{i} \rfloor\) 次操作,可以操作代表的是初始值 \(\leq i\)。那么最后怎么统计答案呢?发现 \(dp_{1,i}\),也就是 \(1\) 被 \(+1\) 的次数为i时,总体是⼀共做了 \(i\) 次总和 \(-1\),所以所有减去的 \(1\) 的总和就是 \(\sum dp_{1,i} \times i\)。
代码:
T3
原题:CF177G2。
对于 \(n \leq 28\),直接暴力做就行。接下来讨论 \(n > 28\) 的情况。
对于一个字符串,设它在 \(f_i\) 的出现次数为 \(g_i\),那么有 \(g_i = g_{i - 1} + g_{i - 2} + x\),\(x\) 表示这个字符串在 \(f_i\) 出现次数减 \(f_{i - 1}\) 出现次数减 \(f_{i - 2}\) 出现次数,即跨越 \(f_{i - 1}\) 和 \(f_{i - 2}\) 的出现次数。观察一下,发现 \(i\) 为奇数时,\(f_i\) 可以被表示为 \(\cdots + f_{26} + f_{26} + \cdots\),最中间的即为 \(f_{i - 1}\) 和 \(f_{i - 2}\) 的分界点;当 \(i\) 为偶数时,\(f_i\) 可以被表示为 \(\cdots + f_{27} + f_{26} + \cdots\),分界点同理。由于 \(f_{26}\) 已经大于 \(10^5\) 了,所以 \(x\) 只分奇数和偶数两种取值,算出这两种取值按照上面的递推式矩阵快速幂优化即可。
暴力和算 \(x\) 我用了 ACAM 解决。好像可以用其他的,应该是我赛时唐了。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5,p=1e9+7;
string s[N];
int n,q,tot=0,ch[N][2],fl[N],cnt[N],id[N],head[N],ecnt=0;
struct node {int to,nxt;}e[N];
void addedge(int u,int v) {e[++ecnt]=(node){v,head[u]};head[u]=ecnt;}
struct matrix {
int c[6][6];
matrix operator*(const matrix &o) const {
matrix x;
memset(x.c,0,sizeof(x.c));
for(int i=1; i<=5; i++)
for(int j=1; j<=5; j++)
for(int k=1; k<=5; k++)
x.c[i][j]=(x.c[i][j]+c[i][k]*o.c[k][j]%p)%p;
return x;
}
}a,ans[N];
matrix qpow(matrix a,int b) {
matrix ans;
memset(ans.c,0,sizeof(ans.c));
for(int i=1; i<=5; i++) ans.c[i][i]=1;
while(b) {
if(b&1) ans=ans*a;
a=a*a;
b>>=1;
}
return ans;
}
void add(string s,int ii) {
int cur=0;
for(int i=0; i<s.size(); i++) {
int b=s[i]-'0';
if(!ch[cur][b]) ch[cur][b]=++tot;
cur=ch[cur][b];
}
id[ii]=cur;
}
void build_fail() {
queue<int> q;
for(int i=0; i<2; i++) if(ch[0][i]) q.push(ch[0][i]);
while(!q.empty()) {
int u=q.front();
q.pop();
for(int i=0; i<2; i++) {
if(ch[u][i]) fl[ch[u][i]]=ch[fl[u]][i],q.push(ch[u][i]);
else ch[u][i]=ch[fl[u]][i];
}
}
}
void query(string t) {
int cur=0;
for(int i=0; i<t.size(); i++) {
int b=t[i]-'0';
cur=ch[cur][b];
cnt[cur]++;
}
}
void dfs(int u) {
for(int i=head[u]; i; i=e[i].nxt) {
int v=e[i].to;
dfs(v);cnt[u]+=cnt[v];
}
}
string make(int lim) {
string s1="0",s2="1",s3;
for(int i=3; i<=lim; i++) {
s3=s2+s1;
s1=s2,s2=s3;
}
return s3;
}
void init1() {
a.c[1][1]=0,a.c[1][2]=0,a.c[1][3]=0,a.c[1][4]=0,a.c[1][5]=0;
a.c[2][1]=0,a.c[2][2]=1,a.c[2][3]=1,a.c[2][4]=0,a.c[2][5]=0;
a.c[3][1]=1,a.c[3][2]=1,a.c[3][3]=2,a.c[3][4]=0,a.c[3][5]=0;
a.c[4][1]=0,a.c[4][2]=1,a.c[4][3]=1,a.c[4][4]=1,a.c[4][5]=0;
a.c[5][1]=0,a.c[5][2]=0,a.c[5][3]=1,a.c[5][4]=0,a.c[5][5]=1;
}
void init2(string t,int ii) {
query(t);dfs(0);
for(int i=1; i<=q; i++) ans[i].c[1][ii]+=cnt[id[i]];
memset(cnt,0,sizeof(cnt));
}
signed main() {
freopen("fib.in","r",stdin);
freopen("fib.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
cin>>n>>q;
for(int i=1; i<=q; i++) cin>>s[i],add(s[i],i);
build_fail();
for(int i=1; i<=tot; i++) addedge(fl[i],i);
if(n<=28) {
string t=make(n);
query(t);dfs(0);
for(int i=1; i<=q; i++) cout<<cnt[id[i]]<<'\n';
} else {
string t1=make(26),t2=make(27),t3=make(28);
init1(),init2(t1,1),init2(t2,2),init2(t3,3),init2(t1+t1,4),init2(t2+t1,5);
for(int i=1; i<=q; i++) ans[i].c[1][4]-=2*ans[i].c[1][1],ans[i].c[1][5]-=ans[i].c[1][1]+ans[i].c[1][2];
matrix tmp=qpow(a,(n-27)/2);
for(int i=1; i<=q; i++) {
ans[i]=ans[i]*tmp;
if(n&1) cout<<ans[i].c[1][2]<<'\n';
else cout<<ans[i].c[1][3]<<'\n';
}
}
return 0;
}
T4
原题:P6305。
洛谷题解讲的挺好,不写了,其实是懒得写。
代码:
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探