In mathematics you don't understand things, you just get used to them.

「CF 1485A」Add and Divide

Link.

贪心。枚举 $[b,b+\log_{2}\text{range}]$ 然后取个 $\min$。

#include<cstdio>
#include<algorithm>
using namespace std;
int t,a,b,ans;
int search(int bas)
{
    if(bas>1)
    {
        int tmp=a,res=0;
        while(tmp>0)
        {
            tmp/=bas;
            res++;
        }
        return res;
    }
    else    return 1e9;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&a,&b);
        if(a==b)    printf("%d\n",2);
        else if(a<b)    printf("%d\n",1);
        else
        {
            ans=1e9;
            for(int i=b;i<=b+233;++i)    ans=min(ans,search(i)+i-b);
            printf("%d\n",ans);
        }
    }
    return 0;
}

「CF 1485B」Replace and Keep Sorted

Link.

每个元素都可以上下摇摆于是预处理前缀差分和和后缀差分和(因为是 strictly increasing 所以要减 $1$)即可。

#include<cstdio>
int n,m,k,a[100010],fro[100010],rea[100010];
void pre()
{
    for(int i=1;i<=n;++i)    fro[i]=a[i]-a[i-1]-1;
    for(int i=n;i>=1;--i)    rea[i]=a[i+1]-a[i]-1;
    for(int i=1;i<=n;++i)    fro[i]+=fro[i-1];
    for(int i=n;i>=1;--i)    rea[i]+=rea[i+1];
}
int main()
{
    scanf("%d %d %d",&n,&m,&k);
    for(int i=1;i<=n;++i)    scanf("%d",&a[i]);
    pre();
    while(m--)
    {
        int l,r;
        scanf("%d %d",&l,&r);
        printf("%d\n",k-a[r]+a[l]-1+fro[r]-fro[l]+rea[l]-rea[r]);
    }
    return 0;
}

「CF 1485C」Floor and Mod

Link.

$$ a\bmod b=\lfloor\frac{a}{b}\rfloor=k \\ \rightarrow a=kb+k\rightarrow a=(b+1)k\rightarrow k=\frac{a}{b+1} \\ k<b\rightarrow k^{2}<k(b+1)=a\le x\rightarrow 1\le k\le\sqrt{x} \\ 1\le a\le x\rightarrow 1\le(b+1)k\le x\rightarrow1\le b\le\frac{x}{k}-1 \\ \rightarrow\text{ans}=\sum_{k=1}^{\sqrt{x}}\max(0,\min(y,\frac{x}{k}-1)-k) $$

#include<cstdio>
#include<algorithm>
using namespace std;
const long long zero=0ll;
long long t,x,y,ans;
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld %lld",&x,&y);
        ans=0;
        for(long long i=1;i*i<=x;++i)    ans+=max(zero,min(y,x/i-1)-i);
        printf("%lld\n",ans);
    }
    return 0;
}

「CF 1485D」Multiples and Power Differences

Link.

  • $(i+j)\bmod 2=1$:$b_{i,j}=\text{lcm}(1,\cdots,16)$。
  • $(i+j)\bmod 2=0$:$b_{i,j}=\text{lcm}(1,\cdots,16)+a_{i,j}^{4}$。

#include<cstdio>
int n,m,x;
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            scanf("%d",&x);
            if((i+j)&1)    printf("%d ",720720);
            else    printf("%d ",720720+x*x*x*x);
        }
        printf("\n");
    }
    return 0;
}

「CF 1485E」Move and Swap

Link.

blue 因为就是一直往下跑,所以一次操作在哪里不影响。

于是设 $f_{u}$ 为操作完毕后 red 跑到 $u$ 的 maximum value。

  • $v\in\text{son}(u)$ 为 red:此时没发生 swapping,$f_{u}=f_{v}+|a_{u}-a_{v}|$。
  • $v\in\text{son}(u)$ 为 blue:此时发生了 swapping,那么枚举 $v$ 的同层结点 $anov$,$f_{u}=f_{anov}+|a_{u}-a_{anov}|$。

#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
const long long INF=1e18;
vector<int> e[200010],same[200010];
int t,n,dep[200010],fa[200010],leaf;
long long a[200010],f[200010];
void dfs(int x,int las)
{
    dep[x]=dep[las]+1;
    fa[x]=las;
    leaf=max(leaf,dep[x]);
    for(int i=0;i<e[x].size();++i)
    {
        int y=e[x][i];
        if(y^las)    dfs(y,x);
    }
}
void DP(int d)
{
    for(int i=d;i>1;--i)
    {
        long long mn=INF,mx=-INF,one=-INF,ano=-INF;
        for(int j=0;j<same[i].size();++j)
        {
            mn=min(mn,a[same[i][j]]);
            mx=max(mx,a[same[i][j]]);
        }
        for(int j=0;j<same[i].size();++j)    f[fa[same[i][j]]]=max(f[fa[same[i][j]]],max(a[same[i][j]]-mn,mx-a[same[i][j]])+f[same[i][j]]);
        for(int j=0;j<same[i].size();++j)
        {
            one=max(one,f[same[i][j]]+a[same[i][j]]);
            ano=max(ano,f[same[i][j]]-a[same[i][j]]);
        }
        for(int j=0;j<same[i].size();++j)    f[fa[same[i][j]]]=max(f[fa[same[i][j]]],max(one-a[same[i][j]],ano+a[same[i][j]]));
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=2;i<=n;++i)
        {
            int x;
            scanf("%d",&x);
            e[x].push_back(i);
            e[i].push_back(x);
        }
        for(int i=2;i<=n;++i)    scanf("%d",&a[i]);
        dfs(1,0);
        for(int i=1;i<=n;++i)    same[dep[i]].push_back(i);
        DP(leaf);
        printf("%lld\n",f[1]);
        for(int i=1;i<=n;++i)
        {
            f[i]=dep[i]=fa[i]=0;
            same[i].clear();
            e[i].clear();
        }
        leaf=0;
    }
    return 0;
}

「CF 1485F」Copy or Prefix Sum

Link.

maths dp greedy number theory

Solution Set -「CF 1490」
上一篇 «
Solution -「LOCAL 28731」「重庆市 2021 中学友谊赛」Rainyrabbit 爱求和
» 下一篇