2019.8.10T1解题报告

题目

C Y j i a n CYjian CYjian最喜欢吃糖了

他现在有 n n n大块糖果 ,每大块糖果有 r [ i ] − l [ i ] + 1 r[i]-l[i]+1 r[i]l[i]+1小块糖果 ,每小块糖果的甜蜜度为 l [ i ] , l [ i ] + 1 , l [ i ] + 2...... r [ i ] l[i],l[i]+1,l[i]+2......r[i] l[i],l[i]+1,l[i]+2......r[i],

现在他可以从每块大糖果中任选一块小糖果来组成他的糖果拼盘 ,

设选出来的糖果的甜蜜度为x[1],x[2]…x[n] ,

m a x ( x [ 1 ] , x [ 2 ] . . . x [ n ] ) = h max(x[1],x[2]...x[n])=h max(x[1],x[2]...x[n])=h

定义这个糖果拼盘的幸福指数为 ∏ i = 1 n ( h − x [ i ] + 1 ) \prod_{i=1}^n (h-x[i]+1) i=1n(hx[i]+1)

现在CYJian要问你 ,他选出的拼盘的所有方案的幸福指数之和为多少?(输出答案对1e9+7取模的结果)

(如果看不懂题 ,可以依照样例进行理解)

数论题/笑哭

好吧真的好考数学

心路历程:

哇塞这道题目什么东西???

大模拟所有情况累加的复杂度都大大超过了限度

貌似是???

( r [ i ] − l [ i ] ) n (r[i]-l[i])^n (r[i]l[i])n

10 的 500 次 方 ? ? ? ? 10的500次方???? 10500????

好吧真的数论题

所以不做了

咳咳

作为一个不是很会用数学公式优化的人,我在考试时只打了一个暴力

但是解题报告的话的还是要认真写一下

写代码的话,首先

emmmmm

首先写个快读

当一个人不会写代码时,就会写个快读冷静一下 \color{blue}\text{当一个人不会写代码时,就会写个快读冷静一下} 当一个人不会写代码时,就会写个快读冷静一下

——沃兹基硕德

然后呢…

写快写

那不是会无聊死/笑哭

肯定是输入啦

/被乱棍打死

/鼻青脸肿爬起来

好吧

先要找到左右端点的最大值,这样确定后面枚举最大数的范围

然后枚举一波

先贴代码吧,

Code:

#include<bits/stdc++.h>
#define ll long long 
const int MAXN=110;
const int mod=1e9+7;
using namespace std;
ll l[MAXN],r[MAXN],ans=0,T,Ma_r,Ma_l,n,tmp;
inline void read(register ll &b){
	register char ch;register ll sum=0,f=1;
	while(ch=getchar(),ch>'9' || ch<'0')if(ch=='-')f=-1;
	while(ch<='9'&&ch>='0') sum=sum*10+ch-'0',ch=getchar();
	b=sum*f;
}
inline ll solve(ll h1,ll h2){
    ll res=1;
    for(int i=1;i<=n;i++){
        ll M_len=min(r[i],h1);
        ll sum=(((M_len-l[i]+1)%mod)*((l[i]+M_len)%mod))/2%mod;
        sum=((M_len-l[i]+1)%mod)*(h2+1)%mod-sum;
        res=res*sum%mod;
    }
    return res%mod;
}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    read(n);
    for(int i=1;i<=n;i++)  
		read(l[i]),read(r[i]);
    for(int i=1;i<=n;i++)
        Ma_l=max(Ma_l,l[i]),
        Ma_r=max(Ma_r,r[i]);
    for(ll i=Ma_l;i<=Ma_r;i++)
        tmp=((solve(i,i)-solve(i-1,i))+mod)%mod,
        ans=(ans+tmp)%mod;
   	cout<<ans;
    return 0;
}

还要解释为什么要枚举一个最大值

可以把每一个大糖看做几个点

像这样:

上面一块,下面一块

首先枚举 h h h方便计算

因为 h h h要满足它是最大的,所以满足要求的话,比他小的数字是不能两两相连的

所以如图,当 h = 3 h=3 h=3时,黑线不满足要求,红线是可以连上的


所以我们的思路就是快速找到红线所示而且求解

在代码中, s o l v e solve solve的第一个参数可以除去最大的那些点,而 M l e n Mlen Mlen指的是剩下的所有的最大点的值

第二个参数指的就是最大值,用于计算的 h h h

而很容易发现,其实每个大糖果都是一个等差数列

相乘的话由于分配率,没有最大点的那些糖果是都要乘起来的,所以可以把这一系列的糖果给乘掉,

然后就是求红线

可以发现,红线就是所有的线减去黑线得到的

所有的线即全匹配,黑线即删去有最大点的糖果的全匹配

所以 s o l v e solve solve这样就可以求出红线了

所以就出来了啦

完毕啦

撒花 \color{red}\text{撒花} 撒花

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值