30/5/0
第一题
tarjin+缩点
缩点建边的时候,以为一个双连通分量low值是一样的,结果居然不一样,这少了30。
结论是(叶子节点数+1)/2;
我打的叶子节点数-1,这少了40
就30了。
第二题
状压dp(表示不会)
本来是手玩的40分
结果玩漏了一个,还玩错了一个就只有5分
上波正解
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
const int maxn=505;
const int mod=1000000007;
int p[]={2,3,5,7,11,13,17,19};
int T,n,k,a[maxn],sta[maxn],dp[maxn][259];
unsigned char temp[maxn];
vector<int>v[maxn];
inline void inc(register int &a,register int &b)
{
a=a+b>mod ? a+b-mod:a+b;
}
int main()
{
freopen("mul.in","r",stdin);
freopen("mul.out","w",stdout);
cin>>T;
while(T--)
{
n=read();
k=read();
for(int i=1;i<=n;i++) v[i].clear(),sta[i]=0;
for(int i=1;i<=n;i++)
{
a[i]=i;
for(int j=0;j<8;j++)
if(a[i]%(p[j]*p[j])==0)sta[i]=-1;
else if(a[i]%p[j]==0) a[i]/=p[j],sta[i]|=(1<<j);
}
for(int i=1;i<=n;i++)
{
if(~sta[i])
{
if(a[i]==1)v[i].push_back(i);
else v[a[i]].push_back(i);
}
}
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
if(~sta[i]&&v[i].size())
{
register int sz=v[i].size();
for(int j=0;j<sz;j++) temp[j]=sta[v[i][j]];
for(register int j=k-1;j>=0;j--)
for(register int l=0;l<sz;l++)
for(register int v=temp[l],s=255^v;;s=(s-1)&(255^v))
{
if((s&temp[l])==0) inc(dp[j+1][s|v],dp[j][s]);
if(!s)break;
}
}
}
long long ans=0;
for(register int i=1;i<=k;i++)
for(register int j=0;j<256;j++)
{
ans+=dp[i][j];
}
cout<<ans%mod<<endl;
}
return 0;
}
第三题
一道结论题,并没有看出来
打的暴力快速幂 本来有30的
结果脑抽,加了个快速乘(以为叫快速乘应该要快点,结果苍天弄人),直接T了