小R打怪兽

题目描述

这里写图片描述

推式子

首先我们设Bi=max(ADi,1)
mi=1XjHjYj[nj=1[HjBji]k]
这让我们很不好搞,但是我们可以容斥,枚举若干个,然后要求这些一定要击败,其余则随意。容斥系数见博客置顶文章容斥的原理及广义应用中的方法求出。接下来我们用f表示容斥系数。
mi=1Sf(|S|)XjHjYjΠjS[HjBji]
mi=1Sf(|S|)Πnj=1([jS](YjXj+1)+[jS]YjHj=Xj[HjBji])
mi=1Sf(|S|)Πnj=1([jS](YjXj+1)+[jS]max(min(Yj,Bji)Xj+1),0))
观察最后那个又有max又有min的东西,现在可以注意到对于每个j可以找到两个i作为分界点,在不同的i值域区间里最后那个式子会有不同的取值。
我们把所有关键点提取出来排序,然后现在关键点之间的区间里每个j影响固定了,我们考虑怎么计算答案。
我们设ff[i,j,k]表示考虑到第i个怪物,目前往S里选了j个怪物(这一维方便我们最后乘上容斥系数),然后有k个过了第一个分界点但是没过第二个分界点的(此时这样的怪物贡献是BjiXj+1,可以把它给展开掉),我们选择了k个Bji(当然我们还没有乘上i)。这一维我们最后需要给它乘一个自然数幂和。

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int maxn=50+10,mo=1000000007;
int f[maxn],ff[maxn][maxn][maxn],c[maxn][maxn],su[maxn][maxn],S[maxn],g[maxn],gg[maxn];
int x[maxn],y[maxn],d[maxn],b[maxn];
struct dong{
    int x,y;
    friend bool operator <(dong a,dong b){
        return a.x<b.x||a.x==b.x&&a.y>b.y;
    }
} p[maxn*2];
bool bz[maxn],pd[maxn];
int i,j,k,l,t,n,m,q,a,tot,top,ans;
void getS(int n,int m){
    int i,j,k,t;
    if (n<0){
        fo(i,0,m) S[i]=0;
        return;
    }
    S[0]=n;
    fo(i,1,m){
        t=1;
        fd(j,n+1,n-i+1)
            if (j%(i+1)==0) t=(ll)t*(j/(i+1))%mo;else t=(ll)t*j%mo;
        fo(j,0,i-1){
            k=(ll)su[i][j]*S[j]%mo;
            if ((i+j)%2==0) (t-=k)%=mo;else (t+=k)%=mo;
        }
        S[i]=t;
    }
}
void work(int l,int r){
    int i,j,k,t;
    fo(i,0,n)
        fo(j,0,n)
            fo(k,0,n)
                ff[i][j][k]=0;
    ff[0][0][0]=1;
    fo(i,0,n-1)
        fo(j,0,i)
            fo(k,0,j)
                if (ff[i][j][k]){
                    (ff[i+1][j][k]+=(ll)ff[i][j][k]*(y[i+1]-x[i+1]+1)%mo)%=mo;
                    if (pd[i+1]){
                        if (bz[i+1]) (ff[i+1][j+1][k]+=(ll)ff[i][j][k]*(y[i+1]-x[i+1]+1)%mo)%=mo;
                        else{
                            (ff[i+1][j+1][k]+=(ll)ff[i][j][k]*(1-x[i+1])%mo)%=mo;
                            (ff[i+1][j+1][k+1]+=(ll)ff[i][j][k]*b[i+1]%mo)%=mo;
                        }
                    }
                }
    getS(l-1,n);
    fo(i,0,n) g[i]=S[i];
    getS(r,n);
    fo(i,0,n) gg[i]=S[i];
    fo(j,0,n)
        fo(k,0,j)
            (ans+=(ll)ff[n][j][k]*f[j]%mo*(gg[k]-g[k])%mo)%=mo;
}
int main(){

    scanf("%d%d%d%d",&n,&m,&q,&a);
    fo(i,1,n){
        scanf("%d%d%d",&d[i],&x[i],&y[i]);
        b[i]=max(1,a-d[i]);
    }
    c[0][0]=1;
    su[0][0]=1;
    fo(i,1,n){
        c[i][0]=1;
        fo(j,1,i){
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
            su[i][j]=(su[i-1][j-1]+(ll)su[i-1][j]*(i-1)%mo)%mo;
        }
    }
    fo(i,0,n){
        t=0;
        fo(j,0,i-1) (t+=(ll)c[i][j]*f[j]%mo)%=mo;
        if (i>=q) f[i]=1-t;else f[i]=-t;
    }
    fo(i,1,n){
        t=x[i]/b[i];
        if (x[i]%b[i]) t++;
        p[++top].x=t;
        p[top].y=i;
        t=(y[i]+1)/b[i];
        if ((y[i]+1)%b[i]) t++;
        p[++top].x=t;
        p[top].y=i;
    }
    p[++top].x=m;
    p[++top].x=1;
    p[top].y=-1;
    sort(p+1,p+top+1);
    fo(i,1,top){
        if (p[i].y==0){
            work(m,m);
            break;
        }
        if (p[i].y>0){
            j=p[i].y;
            if (!pd[j]) pd[j]=1;else bz[j]=1;
        }
        if (p[i].x>=1&&p[i].x<p[i+1].x) work(p[i].x,p[i+1].x-1);
    }
    (ans+=mo)%=mo;
    printf("%d\n",ans);
}
[CSP-S 2024 T1] 决斗 暂无标签 时间限制: 1000MS空间限制: 256MB 难度:入门 题目描述 今天是小 Q 的生日,他得到了 n 张卡牌作为礼物。这些卡牌属于火爆的“决斗怪兽”,其中,第 i 张卡代表一只攻击力为 r i ​ ,防御力也为 r i ​ 的怪兽。 一场游戏分为若干回合。每回合,小 Q 会选择某只怪兽 i 以及另一只怪兽 j(i  =j),并让怪兽 i 向怪兽 j 发起攻击。此时,若怪兽 i 的攻击力小于等于怪兽 j 的防御力,则无事发生;否则,怪兽 j 的防御被打破,怪兽 j 退出游戏不再参到剩下的游戏中。一只怪兽在整场游戏中至多只能发起一次攻击。当未退出游戏的怪兽都已发起过攻击时,游戏结束。 小 Q 希望决定一组攻击顺序,使得在游戏结束时,未退出游戏的怪兽数量尽可能少。 输入格式 输入的第一行包含一个正整数 n,表示卡牌的个数。 输入的第二行包含 n 个正整数,其中第 i 个正整数表示第 i 个怪兽的攻击力及防御力 r i ​ 。 输出格式 输出一行包含一个整数表示游戏结束时未退出游戏的怪兽数量的最小值。 样例输入 1 5 1 2 3 1 2 样例输出 1 2 样例输入 2 10 136 136 136 2417 136 136 2417 136 136 136 样例输出 2 8 提示/说明 样例解释 样例一:其中一种最优方案为:第一回合让第 2 只怪兽向第 1 只怪兽发起攻击,第二回合让第 5 只怪兽向第 4 只怪兽发起攻击,第三回合让第 3 只怪兽向第 5 只怪兽发起攻击。此时没有退出游戏的怪兽都进行过攻击,游戏结束。可以证明没有更优的攻击顺序。 数据范围 对于所有测试数据,保证:1≤n≤10 5 ,1≤r i ​ ≤10 5 。 测试点 n r i ​ 特殊性质 1∼4 ≤10 ≤10 5 无特殊性质 5∼10 ≤10 5 ≤2 无特殊性质 11∼15 ≤30 ≤10 5 特殊性质 A 16∼20 ≤10 5 ≤10 5 无特殊性质 特殊性质 A:保证每个 r i ​ 在可能的值域中独立均匀随机生成。
最新发布
10-19
# P11231 [CSP-S 2024] 决斗 ## 题目描述 今天是小 Q 的生日,他得到了 $n$ 张卡牌作为礼物。这些卡牌属于火爆的“决斗怪兽”,其中,第 $i$ 张卡代表一只攻击力为 $r_i$,防御力也为 $r_i$ 的怪兽。 一场游戏分为若干回合。每回合,小 Q 会选择某只怪兽 $i$ 以及**另一只**怪兽 $j(i \neq j)$,并让怪兽 $i$ 向怪兽 $j$ 发起攻击。此时,若怪兽 $i$ 的攻击力小于等于怪兽 $j$ 的防御力,则无事发生;否则,怪兽 $j$ 的防御被打破,怪兽 $j$ 退出游戏不再参到剩下的游戏中。一只怪兽在整场游戏中**至多**只能发起一次攻击。当未退出游戏的怪兽都已发起过攻击时,游戏结束。 小 Q 希望决定一组攻击顺序,使得在游戏结束时,未退出游戏的怪兽数量尽可能少。 ## 输入格式 输入的第一行包含一个正整数 $n$,表示卡牌的个数。 输入的第二行包含 $n$ 个正整数,其中第 $i$ 个正整数表示第 $i$ 个怪兽的攻击力及防御力 $r_i$。 ## 输出格式 输出一行包含一个整数表示游戏结束时未退出游戏的怪兽数量的最小值。 ## 输入输出样例 #1 ### 输入 #1 ``` 5 1 2 3 1 2 ``` ### 输出 #1 ``` 2 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 10 136 136 136 2417 136 136 2417 136 136 136 ``` ### 输出 #2 ``` 8 ``` ## 说明/提示 **【样例 1 解释】** 其中一种最优方案为:第一回合让第 $2$ 只怪兽向第 $1$ 只怪兽发起攻击,第二回合让第 $5$ 只怪兽向第 $4$ 只怪兽发起攻击,第三回合让第 $3$ 只怪兽向第 $5$ 只怪兽发起攻击。此时没有退出游戏的怪兽都进行过攻击,游戏结束。可以证明没有更优的攻击顺序。 **【样例 3】** 见选手目录下的 duel/duel3.in duel/duel3.ans。 该样例满足 $\forall 1 \leq i \leq n, r_i \leq 2$。 **【样例 4】** 见选手目录下的 duel/duel4.in duel/duel4.ans。 **【数据范围】** 对于所有测试数据,保证:$1 \leq n \leq 10^5$,$1 \leq r_i \leq 10^5$。 | 测试点 | $n$ | $r_i$ | 特殊性质 | | :----------: | :----------: | :----------: | :----------: | | $1\sim 4$ | $\leq 10$ | $\leq 10^5$ | 无特殊性质 | | $5\sim 10$ | $\leq 10^5$ | $\leq 2$ | 无特殊性质 | | $11\sim 15$ | $\leq 30$ | $\leq 10^5$ | 特殊性质 A | | $16\sim 20$ | $\leq 10^5$ | $\leq 10^5$ | 无特殊性质 | 特殊性质 A:保证每个 $r_i$ 在可能的值域中独立均匀随机生成。
04-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值