牛客 小白月赛90. D---小A的线段 dfs+差分数组优化

D-小A的线段(easy-version)_牛客小白月赛90.png

题解

看csdn题解顺便复习了一下差分数组的知识 全忘光了
实际上差分数组b[i]就是将每个a[i]拆解
a[i]是b[0] + …… + b[i]
他的实现就是通过输入时每次赋值时b[i] = a[i] - a[i - 1]
将b[i]实现为从a[i - 1]走向a[i]需要加上b[i]
举例 a[3] = a[2] + b[3] 同时 a[2] = a[1] + b[2] 所以 a[3] = b[1] + b[2] + b[3]
那么当我们对b[1]+1 那他会使得a[1]及之后的数都加上+1 因为每个a[i]里面都含有b[1]
所以有公式 b[l] += c; b[r + 1] -= c; 就可以将序列中a[l, r]之间的每个数都加上c
当我们要输出a[i]时 就可以对b[i]作前缀和来求a[i]

for (int i = 1; i <= n; i++)
    {
        a[i] = b[i] + a[i - 1];    //前缀和运算
        printf("%d ", a[i]);
    }

差分题解
好了 这个问题解决了
解决dfs
我们可以一条一条线段的搜
当搜到某条线段时 分成选择该线段和不选该线段两种方式
选择该线段就把该线段标记为true 反之为false (记得恢复现场)
当把所有线段都搜完了 我们就可以判断是否每个整数点都被覆盖了两次
当我们选择某一线段时 怎么通过线段的两个端点去让这一区间内的整数点的覆盖次数都加1
利用差分数组
这道题不用初始化差分数组 初始每个整数点的覆盖次数都是0 那差分数组所有值也都是0
上代码

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10, M = 20, mod = 998244353; //N是整数点区间上限 M是线段个数上限

int n, m;
long long ans; //ans是方案数
int l[M], r[M]; //存线段的左右节点坐标
bool st[M]; //记录该线段是否使用过
int b[N]; //差分数组

void dfs(int u)
{
    if (u > m) //如果最后一条线段已经搜完
    {
        memset(b, 0, sizeof b);
        for (int i = 1; i <= m; i ++ )
        {
            //找使用过的线段 将其区间内的整数点覆盖次数加1
            if(st[i])
            {
                //cout << u << endl;
                b[l[i]] ++ ;
                b[r[i] + 1] -- ;
            }
        }

        //找完之后使用过的线段内的整数点覆盖次数都确定了 开始搜是否每个点覆盖次数都至少为2次
        for (int i = 1; i <= n; i ++ )
        {
            b[i] = b[i - 1] + b[i]; //求差分数组前缀和 求出来每个点的前缀和也就是每个点的覆盖次数
            if (b[i] < 2) return; //只要有一个点不满足覆盖次数大于等于2 直接返回
        }
        ans = ans + 1; //进行到这里证明没有return 每个整数点都满足要求 方案数+1
        ans %= mod;
        return;
    }
    //当不选择该线段
    st[u] = false;
    dfs(u + 1);

    //当选择该线段
    st[u] = true;
    dfs(u + 1);
    st[u] = false; //恢复现场
}

void solve()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i ++ )
    {
        scanf("%d%d", &l[i], &r[i]);
    }
    dfs(1);
    printf("%d\n", ans % mod);
    return;
}

int main()
{
    solve();

    return 0;
}
posted @ 2024-04-16 15:52  MsEEi  阅读(8)  评论(0)    收藏  举报