2019暑假记录下

痞子三分冷 提交于 2019-11-29 01:34:01

8.26 Day1
  爆零祭,跑8圈预定祭,被Tham D祭
  T1 书堆(a)
  题意:bzoj 2048
  题解:可看出\(ans=m* \sum_{i=1}^{n}{\frac{1}{2i}}\)(虽然我这个物理菜狗并没有看出来)
  然后有一个玄学的调和级数近似公式
  \[\sum_{i=1}^{n}{\frac{1}{i}}=\ln(n)+\gamma\]
  其中\(\gamma\)为欧拉常数,约等于\(0.57721566\)(背了就行)
  注意这只是一个近似公式
  复杂度\(O(1)\sim O(n)\)

#include<bits/stdc++.h>
using namespace std;

int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    long long n,m,ans;
    long double f=0;
    scanf("%lld%lld",&n,&m);
    if(n<=1e7)
        for(int i=2;i<=n<<1;i+=2) f+=1.0/i;
    else f=(log(n)+0.5772156649)/2;
    ans=f*m-1e-6;
    printf("%lld\n",ans);
    return 0;
}

  T2 最长距离 b
  题意:bzoj 1295
  题解:对于每个点跑一遍spfa求出以当前点为起点符合条件的路径(即障碍物数小于等于T)
  复杂度:\(O(n^2m^2+nm*spfa)\)

#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
int n,m,t,ans,G[32][32],vis[32][32],dis[32][32];
int d[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
char s[40];
queue<pair<int,int> > q;
void spfa(int sx,int sy)
{
    memset(vis,0,sizeof(vis));
    memset(dis,0x7f,sizeof(dis));
    vis[sx][sy]=1;
    dis[sx][sy]=G[sx][sy];
    q.push(mp(sx,sy));
    while(!q.empty())
    {
        int tx=q.front().first,ty=q.front().second;
        vis[tx][ty]=0;
        q.pop();
        for(int i=0;i<4;++i)
        {
            int tmpx=tx+d[i][0],tmpy=ty+d[i][1];
            if(tmpx&&tmpy&&tmpx<=n&&tmpy<=m)
            {
                if(dis[tmpx][tmpy]>dis[tx][ty]+G[tmpx][tmpy])
                {
                    dis[tmpx][tmpy]=dis[tx][ty]+G[tmpx][tmpy];
                    if(!vis[tmpx][tmpy])
                        q.push(mp(tmpx,tmpy)),vis[tmpx][tmpy]=1;
                }
            }
        }
    }
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            if(dis[i][j]<=t)
            {
                int tmp=(sx-i)*(sx-i)+(sy-j)*(sy-j);
                if(tmp>ans) ans=tmp;
            }
}
int main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=n;++i)
    {
        scanf("%s",s+1);
        for(int j=1;j<=m;++j)
            G[i][j]=(s[j]=='0'?0:1);
    }
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            spfa(i,j);
    printf("%.6lf",sqrt(ans));
    return 0;
}

  T3 聚会 c
  题意:bzoj 1832
  题解:一开始以为是个图就自闭了,后面突然发现是棵树然后赶紧写掉,结果分类讨论写挂了直接枚举lca即可
  复杂度:\(O(n\log n)\)

#include<bits/stdc++.h>
using namespace std;
#define maxn 500005
struct Edge
{
    int fr,to;
}eg[maxn<<1];
int head[maxn],edgenum,n,m,deep[maxn],fa[maxn][20],ln;
inline void add(int fr,int to)
{
    eg[++edgenum]=(Edge){head[fr],to};
    head[fr]=edgenum;
}
inline void dfs(int rt,int fat,int dep)
{
    deep[rt]=dep;
    fa[rt][0]=fat;
    for(int i=head[rt];i;i=eg[i].fr)
        if(eg[i].to!=fat) dfs(eg[i].to,rt,dep+1);
}
inline int lca(int x,int y)
{
    if(deep[x]<deep[y]) swap(x,y);
    int dist=deep[x]-deep[y];
    for(int i=0;i<=ln;++i)
        if((1<<i)&dist) x=fa[x][i];
    if(x==y) return x;
    for(int i=ln;i>=0;--i)
        if(fa[x][i]!=fa[y][i])
            x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
inline int getdis(int x,int y)
{
    return deep[x]+deep[y]-2*deep[lca(x,y)];
}
int main()
{
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    scanf("%d%d",&n,&m);
    int a,b,c;
    for(int i=1;i<n;++i)
    {
        scanf("%d%d",&a,&b);
        add(a,b),add(b,a);
    }
    dfs(1,0,0);
    ln=log(n)/log(2)+1;
    for(int i=1;i<=ln;++i)
        for(int j=1;j<=n;++j)
            fa[j][i]=fa[fa[j][i-1]][i-1];
    for(int i=1;i<=m;++i)
    {
        scanf("%d%d%d",&a,&b,&c);
        int l1=lca(a,b),l2=lca(a,c),l3=lca(b,c);
        if(l1==l2) printf("%d %d\n",l3,getdis(l3,a)+getdis(l3,b)+getdis(l3,c));
        else if(l1==l3) printf("%d %d\n",l2,getdis(l2,a)+getdis(l2,b)+getdis(l2,c));
        else if(l2==l3) printf("%d %d\n",l1,getdis(l1,a)+getdis(l1,b)+getdis(l1,c));
    }
    return 0;
}

  T4 地精部落 d
  题意:bzoj 1925
  题解:神仙dp。题解直接度娘吧。代码奇短好评
  复杂度:\(O(n^2)\)

#include<bits/stdc++.h>
using namespace std;
#define maxn 5005
int dp[maxn][maxn];
int main()
{
    int n,mod,ans=0;
    scanf("%d%d",&n,&mod);
    dp[1][1]=dp[2][2]=1;
    for(int i=3;i<=n;++i)
    {
        for(int j=2;j<=i;++j)
            dp[i][j]+=dp[i][j-1]+dp[i-1][i-j+1],dp[i][j]%=mod;
    }
    for(int i=2;i<=n;++i)
        ans+=dp[n][i],ans%=mod;
    ans<<=1;
    ans%=mod;
    printf("%d\n",ans);
    return 0;
}

  T5 纪念品盒 e
  题意:bzoj 4368
  题解:贪心。也是度娘吧。
  复杂度:\(O(n)\)

#include<bits/stdc++.h>
using namespace std;
#define maxn 10000005
int l[maxn],r[maxn],pos[maxn],n,k,L;
long long LL[maxn],RR[maxn];
int main()
{
    freopen("e.in","r",stdin);
    freopen("e.out","w",stdout);
    scanf("%d%d%d",&n,&k,&L);
    for(int i=1;i<=n;++i)
        scanf("%d",&pos[i]);
    int lenl=0,lenr=0;
    for(int i=1;i<=n;++i)
    {
        if(!pos[i]) continue;
        if((pos[i]<<1)<=L) l[++lenl]=pos[i];
        else r[++lenr]=pos[i];
    }
    for(int i=1;i<=lenr>>1;++i) swap(r[i],r[lenr-i+1]);
    for(int i=1;i<=lenl;++i)
    {
        if(i<=k) LL[i]=l[i]<<1;
        else LL[i]=LL[i-k]+(l[i]<<1);
    }
    for(int i=1;i<=lenr;++i)
    {
        if(i<=k) RR[i]=(L-r[i])<<1;
        else RR[i]=RR[i-k]+((L-r[i])<<1);
    }
    long long ans=LL[lenl]+RR[lenr];
    for(int i=0;i<k;++i)
        ans=min(ans,LL[lenl-i]+RR[max(0,lenr+i-k)]+L);
    printf("%lld\n",ans);
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!