1002.RGCDQ
题意:F[x]为x的质因子数,给出一个区间,求该区间内的MAXgcd(F[i],F[j])
预处理出素数的同时,处理出F[x]
再dp[i][j],处理出到i之前的(包括i)质因子数为j的数量
最后枚举即可
#include <cstdio>
#include <string>
#include <queue>
#include <iostream>
#include <algorithm>
#include <cstring>
#define ll __int64
using namespace std;
//const int N=(100000<<2)+5;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int pri[1000005];
int F[1000005];
int sum[1000005][8];
int main()
{
for(int i=2; i<=1000000; i++)
pri[i]=1,F[i]=0;
for(int i=2; i<=1000000; i++)
if(pri[i])
{
for(int j=(i<<1); j<=1000000; j+=i)
{
pri[j]=0;
F[j]++;
}
F[i]++;
}
// for(int i=2; i<=100; i++)
// cout<<i<<" "<<F[i]<<endl;
sum[1][1]=sum[1][2]=sum[1][3]=sum[1][4]=sum[1][5]=sum[1][6]=sum[1][7]=0;
sum[2][2]=sum[2][3]=sum[2][4]=sum[2][5]=sum[2][6]=sum[2][7]=0;
sum[2][1]=1;
for(int i=3; i<=1000001; i++)
for(int j=1; j<=7; j++)
{
sum[i][j]=sum[i-1][j];
if(F[i]==j)
sum[i][j]++;
}
int t;
cin>>t;
while(t--)
{
int L,R;
scanf("%d%d",&L,&R);
int has[10];
for(int j=1; j<=7; j++)
has[j]=sum[R][j]-sum[L-1][j];
int ma=-1;
for(int j=7; j>=1; j--)
if(has[j]>=2)
{
ma=j;
break;
}
if(ma>=3)
printf("%d\n",ma);
else
{
if(has[3]&&has[6])
printf("3\n");
else if((has[2]&&has[6])||(has[4]&&has[6])||(has[2]&&has[4]))
printf("2\n");
else if(has[2]>=2)
printf("2\n");
else
printf("1\n");
}
}
}
1003.The Goddess Of The Moon
题意:给出n个短链,求由m个短链组成的方法数,一个短链的后缀是另一个短链的前缀(起码2个字符)就认为可以组合。
describe the n kinds of chains. 注意可能重复,需要去重。另外12和12这样的也是可以组合的。
知道题意就很简单了,构造矩阵然后从初始状态开始转移就可以了。
#include <cstdio>
#include <string>
#include <queue>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#define ll __int64
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define CSH(a,b) memset(a,b,sizeof(a))
using namespace std;
const ll mod=1000000007;
int n;
ll m;
string ss[100];
struct ju
{
ll a[80][80];
void init()
{
int i ;
CSH(a,0);
for (i=0; i<79; i++ )
a[i][i]=1;
}
} ti;
ju juadd(ju a,ju b)
{
int i,j;
ju c;
for (i=0; i<n; i++)
for (j=0; j<n; j++)
c.a[i][j]=((a.a[i][j]+b.a[i][j])%mod);
return c;
}
ju jumul(ju a,ju b)
{
int i,j,k;
ju c;
CSH(c.a,0);
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
{
if(a.a[i][j])
for(k=0; k<n; k++)
{
c.a[i][k]+=((a.a[i][j]*b.a[j][k]))%mod;
c.a[i][k]%=mod;
}
}
}
return c ;
}
ju fastshe(ju s,ll k)
{
ju ans;
ans.init();
for(; k>0; k>>=1)
{
if(k&1)
ans=jumul(ans,s);
s=jumul(s,s) ;
}
return ans;
}
int pan(int a,int b)
{
for(int i=2;i<=ss[a].size()&&i<=ss[b].size();i++)
{
int j=0;
for(;j<i;j++)
if(ss[a][ss[a].size()-i+j]!=ss[b][j])
break;
if(j==i)
return 1;
}
return 0;
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%d %I64d",&n,&m);
if(n==0||m==0)
{
printf("0\n");
continue;
}
map<string,int> q;
q.clear();
string tmp;
int cnt=0;
for(int i=0; i<n; i++)
{
cin>>tmp;
if(!q[tmp])
{
ss[cnt++]=tmp;
q[tmp]++;
}
}
n=cnt;
CSH(ti.a,0);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
if(pan(i,j))
ti.a[i][j]=1;
ju ans;
for(int i=0;i<n;i++)
ans.a[0][i]=1;
ti=fastshe(ti,m-1);
ans=jumul(ans,ti);
ll out=0;
for(int i=0;i<n;i++)
{
out+=ans.a[0][i];
out%=mod;
}
printf("%I64d\n",out%mod);
}
}
1004.Painter
这个很水....1008.Solve this interesting problem
给你一个L,R,让你求根节点的0-n的n的最小值
首先父节点长度是否均分两种情况,然后该节点为左右节点两种情况。
所以组合一下4种情况 ,dfs转移剪枝即可。
[L,R + (R - L +1)],[L,R + (R - L + 1) - 1],[L - (R - l + 1),R],[L - (R - l + 1) - 1,R]
#include <cstdio>
#include <string>
#include <queue>
#include <iostream>
#include <algorithm>
#include <cstring>
#define ll __int64
using namespace std;
//const int N=(100000<<2)+5;
//#define lson l,m,rt<<1
//#define rson m+1,r,rt<<1|1
ll ans;
ll Min(ll a,ll b)
{
return a>b?b:a;
}
void dfs(ll l,ll r)
{
if(l>r||l<0) return;
if(l==0)
{
ans=Min(r,ans);
return;
}
ll m=r-l+1;
if(m>l)
return;
dfs(l,r+m);
if(m!=1) dfs(l,r+m-1);
dfs(l-m,r);
dfs(l-m-1,r);
}
int main()
{
ll L,R;
while(~scanf("%I64d%I64d",&L,&R))
{
if(L==0)
{
printf("%I64d\n",R);
continue;
}
ans=1e12;
dfs(L,R);
if(ans==(ll)(1e12))
puts("-1");
else printf("%I64d\n",ans);
}
}