题目
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(h−x[i]+1)
现在CYJian要问你 ,他选出的拼盘的所有方案的幸福指数之和为多少?(输出答案对1e9+7取模的结果)
(如果看不懂题 ,可以依照样例进行理解)
数论题/笑哭
好吧真的好考数学
心路历程:
哇塞这道题目什么东西???
大模拟所有情况累加的复杂度都大大超过了限度
貌似是???
( r [ i ] − l [ i ] ) n (r[i]-l[i])^n (r[i]−l[i])n
10 的 500 次 方 ? ? ? ? 10的500次方???? 10的500次方????
好吧真的数论题
所以不做了
咳咳
作为一个不是很会用数学公式优化的人,我在考试时只打了一个暴力
但是解题报告的话的还是要认真写一下
写代码的话,首先
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这样就可以求出红线了
所以就出来了啦
完毕啦