2024.9.22

今日总结:
1:
本题目是一个用记忆化搜索来实现数位DP
dp[i][j]表示在没有顶上界和前导零的情况下,当前填到了第i位,余数为j的数的个数。
在搜索过程中记一下当前数位和mod p等于多少

点击查看代码
#include<bits/stdc++.h>

using namespace std;

const int Mod = 1e9 + 7;
const int N = 1e4 + 10;

int n,sum,ans;
int dp[N][100];
char s[N];

int main()
{
    scanf("%d%s",&n,s);
    int len = strlen(s);
    dp[0][0] = 1;
    for(int i = 1;i <= len;i ++)
        for(int j = 0;j < n;j ++)
            for(int k = 0;k <= 9;k ++)
            {
                dp[i][(j + k) % n] += dp[i - 1][j];
                dp[i][(j + k) % n] %= Mod;
            }
    for(int i = 0;i < len;i ++)
    {
        int x = s[i] ^ 48;
        for(int j = 0;j < x;j ++)
        {
            ans += dp[len - i - 1][((n << 1) - sum - j) % n];
            ans %= Mod;
        }
        sum += x;
        sum %= n;
    }
    if(sum != 0)
    {
        ans += Mod - 1;
        ans %= Mod;
    }
    printf("%d\n",ans);
    return 0;
}

2:Cosmic Rays
这道题主要考察的是最短路,有一个很重要的结论对于一个覆盖的区域来说,经过它的圆心永远比不经过圆心优,
一条边的边权就是两个点的欧几里德距离减去两个圆的半径。
最后用dijstra求一下最短路即可

点击查看代码
#include<bits/stdc++.h>

using namespace std;

const int N = 1500;
const long long INF = 1e18;

int n;
int X[N],Y[N],R[N];
double dis[N];
bool vis[N];

inline double Dist(int x,int y)
{
    return sqrt(1.*x*x + 1.*y*y);
}

int main()
{
    scanf("%d%d%d%d%d",X + 1,Y + 1,X + 2,Y + 2,&n);
    n += 2;
    for(int i = 3;i <= n;i ++)
        scanf("%d%d%d",X + i,Y + i,R + i);
    for(int i = 2;i <= n;i ++)
        dis[i] = INF;
    for(int T = 1;T < n;T ++)
    {
        int u = 0;
        for(int i = 1;i <= n;i ++)
            if((!u || dis[i] < dis[u]) && !vis[i]) u = i;
        vis[u] = 1;
        for(int i = 1;i <= n;i ++)
            if(u != i && !vis[i])
            {
                double goal = Dist(X[u] - X[i],Y[u] - Y[i]) - R[u] - R[i];
                if(goal < 0) goal = 0;
                if(dis[i] > dis[u] + goal) dis[i] = dis[u] + goal;
            }
    }
    printf("%.15f\n",dis[2] + 1e-15);
    return 0;
}

3:高橋君
这道题主要是用莫队:
首先分析题意

预处理出每个数的逆元、算出阶乘与阶乘的逆元的组合数

点击查看代码
#include<bits/stdc++.h>

using namespace std;

const int M = 520;
const int Mod = 1000000007;
const int N = 1e5 + 10;

#define int long long

int Mo(int x, int y)
{
    int q = 1;
    for(; y; y >>= 1, x = x * x % Mod)
        if (y & 1)
            q = q * x % Mod;
    return q;
}
struct Node
{
    int l, r, i;
}q[N];

int n,dis,z = 1;
int b[N],f[N],val[N],w[N];
inline bool Option(Node x, Node y) 
{
    return b[x.l] == b[y.l] ? b[x.l] & 1 ? x.r < y.r : x.r > y.r : x.l < y.l; 
}

int C(int x, int y) 
{
    return x < y ? 0 : f[x] * val[y] % Mod * val[x - y] % Mod; 
}

signed main()
{
    dis = Mo(2, Mod - 2);
    for(int i = f[0] = 1;i <= 1e5;i ++)
    {
        f[i] = f[i - 1] * i % Mod;
        b[i] = (i - 1) / M + 1;
    }
    val[100000] = Mo(f[100000], Mod - 2);
    for(int i = 1e5 - 1;i >= 0;i --)
        val[i] = val[i + 1] * (i + 1) % Mod;
    scanf("%lld",&n);
    for(int i = 0;i < n;i ++)
    {
        scanf("%lld%lld",&q[i].r,&q[i].l);
        q[i].i = i;
    }   
    sort(q, q + n,Option);
    for(int i = 0,l = 1,r = 0;i < n;i ++)
    {
        while(l > q[i].l)
            z = (z + Mod - C(r, l--)) % Mod;
        while(r < q[i].r)
            z = (z * 2 + Mod - C(r++, l)) % Mod;
        while(l < q[i].l)
            z = (z + C(r, ++l)) % Mod;
        while(r > q[i].r)
            z = (z + C(--r, l)) * dis % Mod;
        w[q[i].i] = z;
    }
    for(int i = 0;i < n;i ++)
        printf("%lld\n", w[i]);
    return 0;
}
posted @ 2024-09-22 22:16  Kevinhwbb  阅读(6)  评论(0编辑  收藏  举报