8.22总结
函数变化
考试最后关头,我才发现T1是有规律的,哭~
写下一个暴力程序,打表后,你可以发现前n-1项中第i项的答案为\(2^{i-1}\),第n项为\(2^{n-1}-1\),n以后项的答案为前n项的和,就可以\(O(n)\)解决问题了。
AC Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline ll read()
{
ll 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*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int N=1e6+5;
const int mod=1e9+9;
ll n,m,f[N];
int main()
{
n=read(),m=read();
ll sum=1;f[1]=1;
for(int i=2;i<=n;i++)
{
f[i]=f[i-1]*2%mod;
if(i==n)f[i]-=1;
sum=(sum+f[i])%mod;
}
for(int i=n+1;i<=m;i++)
{
f[i]=sum;
sum=((sum-f[i-n]+f[i])%mod+mod)%mod;
}
printf("%lld\n",f[m]);
return 0;
}
刺客信条
\(solution\)
二分+并查集
二分红衣教徒的影响范围,然后枚举每个红衣教徒,看是否覆盖上下左右边界,再然后看红衣教徒之间是否相交,最后看上下边界和左右边界是否联通,如果联通则r=mid,否则l=mid;
AC Code
#include<bits/stdc++.h>
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*10+ch-'0';
ch=getchar();
}
return x*f;
}
const double eps=1e-8;
int x,y,n,fa[2005];
int num[2005][2];
struct ww{
int x,y;
}a[2005];
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
bool check(double s)
{
int tmp1=0,tmp2=0;
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++)
{
if(a[i].y-s<eps||a[i].x+s>x+eps)
num[++tmp1][0]=i;
if(a[i].x-s<eps||a[i].y+s>y+eps)
num[++tmp2][1]=i;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(fa[i]==fa[j])continue;
double x_=a[i].x-a[j].x;
double y_=a[i].y-a[j].y;
if(sqrt(x_*x_+y_*y_)<2*s+eps)
{
if(find(i)!=find(j))
fa[find(i)]=fa[find(j)];
}
}
}
for(int i=1;i<=tmp1;i++)
{
for(int j=1;j<=tmp2;j++)
{
if(find(num[i][0])==find(num[j][1]))
return true;
}
}
return false;
}
int main()
{
x=read(),y=read(),n=read();
for(int i=1;i<=n;i++)
a[i].x=read(),a[i].y=read();
double l=0,r=1e6,ans;
while(r-l>=eps)
{
double mid=(l+r)/2.0;
if(check(mid))
{
ans=mid;
r=mid;
}
else l=mid;
}
printf("%.2f",ans);
return 0;
}
摘果子
\(solution\)
连完边后在树上跑一个dfs序,然后01背包模板
注意要存子树大小,不选当前点i的下一个状态是:\(i+siz_i\)
AC Code
#include<bits/stdc++.h>
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*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int N=2e3+5;
const int inf=0x3f3f3f3f;
int n,m;
int v[N],p[N];
int vis[N],d[N],siz[N];
int tot,h[N],ver[N*2],nex[N*2];
int f[N][N],num;
void add(int x,int y)
{
ver[++tot]=y,nex[tot]=h[x],h[x]=tot;
}
void dfs(int x)
{
d[++num]=x;
siz[x]=1;vis[x]=1;
for(int i=h[x];i;i=nex[i])
{
int y=ver[i];
if(vis[y])continue;
dfs(y);
siz[x]+=siz[y];
}
}
int main()
{
// freopen("fruit.in","r",stdin);
// freopen("fruit.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;i++)v[i]=read(),p[i]=read();
int x,y;
for(int i=1;i<n;i++)
{
x=read(),y=read();
add(x,y);add(y,x);
}
dfs(1);
for(int i=0;i<=n+1;i++)
{
for(int j=0;j<=m;j++)f[i][j]=-inf;
}
f[1][0]=0;
for(int i=1;i<=n;i++)
{
x=d[i];
for(int j=0;j<=m;j++)
{
if(j+p[x]<=m)
{
f[i+1][j+p[x]]=max(f[i+1][j+p[x]],f[i][j]+v[x]);
f[i+siz[x]][j+p[x]]=max(f[i+siz[x]][j+p[x]],f[i][j]+v[x]);
}
f[i+siz[x]][j]=max(f[i+siz[x]][j],f[i][j]);
}
}
int ans=0;
for(int i=0;i<=m;i++)ans=max(ans,f[n+1][i]);
printf("%d\n",ans);
return 0;
}

浙公网安备 33010602011771号