K.Last Defences
给定两个数A,B(<1e18)S0=A,S1=B,Si=| Si-1- Si-2 |,求Si不同值的个数
假设A=11,B=3,简单计算可得序列S:11,3,8,5,3,2,1,1,0,1,0~
仔细观察可以看出:8=11-1*3,5=11-2*3,2=11-3*3,3出现的次数为11%3-1,产生的新数字个数为A/B
那么1如何得来的:11%3=2,3-2=1;现在并不容易看出,但多检查几对数可以看出 1是由 B-(A%B)得到的
于是可以想到,一个递推过程DFS(A,B)=A/B+DFS(B,A%B)
其中几项要特判A==B==0,A==0||B==0,A==B,另外若A%B==0,假设A=4,B=2,它们所贡献的答案为除A和B本身之外有1,0,
其中的1时A-B,在A/B的时候已经计算过了所以需要减去,所以此时的贡献为A%B-1;
#include<bits/stdc++.h>
using namespace std;
long long A,B;
int t;
long long dfs(long long a,long long b)
{
if(a%b==0) return a/b-1;
long long x=a%b,y=a/b;
return y+dfs(b,x);
}
int main()
{
scanf("%d",&t);
for(int tc=1;tc<=t;++tc)
{
scanf("%lld%lld",&A,&B);
if(A==B&&A==0) {printf("Case #%d: 1\n",tc);continue;}
if(A==B||A==0||B==0) {printf("Case #%d: 2\n",tc);continue;}
printf("Case #%d: %lld\n",tc,dfs(A,B)+2);
}
return 0;
}
G.the problem to slow down you
给定两个字符串,求其相同的回文串的个数
2个回文自动机对着跑,答案为相同节点上回文串的乘积的和
#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+5;
struct Trie
{
static const int MAXN=26;
int nxt[MAX][MAXN],f[MAX],cnt[MAX],num[MAX],len[MAX],c[MAX],last,n,L;
int newnode(int x)
{
for(int i=0;i<MAXN;++i) nxt[L][i]=0;
cnt[L]=num[L]=0;len[L]=x;return L++;
}
void init()
{
L=0;newnode(0);newnode(-1);
last=0;n=0;c[n]=-1;f[0]=1;
}
int getf(int x)
{
while(c[n-len[x]-1]!=c[n]) x=f[x];
return x;
}
void add(int x)
{
c[++n]=x;
int cur=getf(last);
if(!nxt[cur][x])
{
int now=newnode(len[cur]+2);
f[now]=nxt[getf(f[cur])][x];
nxt[cur][x]=now;
num[now]=num[f[now]]+1;
}
++cnt[last=nxt[cur][x]];
}
void count()
{
for(int i=L-1;i>=2;--i) cnt[f[i]]+=cnt[i];
}
}PT1,PT2;
char s1[MAX],s2[MAX];
int t;
long long dfs(int u,int v)
{
long long tmp=0;
for(int i=0;i<26;++i)
{
if(PT1.nxt[u][i]&&PT2.nxt[v][i])
{
tmp+=1ll*PT1.cnt[PT1.nxt[u][i]]*PT2.cnt[PT2.nxt[v][i]];
tmp+=dfs(PT1.nxt[u][i],PT2.nxt[v][i]);
}
}
return tmp;
}
int main()
{
scanf("%d",&t);
for(int tc=1;tc<=t;++tc)
{
scanf("%s%s",s1,s2);
PT1.init();PT2.init();
int L1=strlen(s1),L2=strlen(s2);
for(int i=0;i<L1;++i) PT1.add(s1[i]-'a');
for(int i=0;i<L2;++i) PT2.add(s2[i]-'a');
PT1.count(),PT2.count();
printf("Case #%d: %lld\n",tc,dfs(0,0)+dfs(1,1));
}
return 0;
}