这场是第一场没有米的BC...

  大概也是想震一震那些一听说没米了就不打BC的人吧

  这次的题目质量比以往高了许多

  (然而我并没有打这一场BC

  但是今天下午到现在做的过程中真的学到了不少知识呢


  A题略水...

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
int T,n;
int main(){
scanf("%d",&T);
while (T--){
scanf("%d",&n);
int tmp;
for (int i=;i<=sqrt(n);i++) if (n%i==) tmp=i;
printf("%d\n",*(n/tmp+tmp));
}
return ;
}

  然而第二题就不是非常简单的呢...

  开始啊..我打算数位DP搞搞,然而突然发现排列是不能有重复数字的啊...

  想到一个容易入手的状态 也就解决了这道题

  我们需要让这些排列都小于读进来的排列

  然后思考一下这些排列都有什么共性呢?

  显然一定是由一段与排列相同的数字组成的前缀构成的,而接下来的一位一定小于排列,剩下的就随意了

  这么一来好像问题就迎刃而解了

  枚举与原串相同的位数(0~n-1),以及接下来一位的数字(小于原串该位置上的数字且在前面的位置中没出现过)

  

  设当前枚举的黄色部分的位置为i,那么显然这样的字符串有(n-i)!种(即后面蓝色部分的n-i个数字的全排列)

  这些字符串对答案的贡献分几部分考虑

  1)红色部分内部的逆序对*(n-i)!,原串所有的前缀的逆序对数量可以通过树状数组预处理出

  2)红色部分与黄色+蓝色部分的逆序对数,

可以用树状数组维护黄色+蓝色部分的值(即每向后走一格就将前一个数从树状数组中删去)

然后枚举红色部分的每一个元素,统计逆序对数,最后乘上(n-i)!

  3)黄色部分与蓝色部分的逆序对数,直接与红色部分一样的答案最后-1即可(即把自己与自己减掉),

当然get的时候传参改成数值-1也是可以的

  4)蓝色部分的逆序对数,这个在(n-i)!个字符串中都是不一样的,于是我们可以考虑总数

对于一个n个数的排列,我们考虑其中的两个数,它们成为逆序对的次数为C(n,2)*(n-2)!

所以逆序对总数为C(n,2)^2*(n-2)!

  然后这道题就做完了,但是却对拍了一个下午都没找出哪里写错...

  最后写两点做题过程中积累的东西吧...

  1)C++的数组和Pas毕竟不一样...赋值啊什么的不能顶到maxn..而且居然本地不会出现RE

  2)while not eof do 在C++里是以很奇怪的方式替代的呢...

 #include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<cstring>
#define tt 1000000007
#define maxn 110
#define ll long long
using namespace std;
int n,a[maxn],tr[maxn];
ll w[maxn],p[maxn],b[maxn];
bool used[maxn];
int get(int x){
int tmp=;
while (x) tmp+=tr[x],x-=x&(-x);
return tmp;
}
void put(int x,int y){
while (x<=n) tr[x]+=y,x+=x&(-x);
}
void build(){
w[]=;for(int i=;i<maxn;i++) w[i]=(w[i-]*i)%tt;
p[]=;for (int i=;i<maxn;i++) {
ll tmp=i*(i-)/;
p[i]=((tmp*tmp%tt)*w[i-])%tt;
}
}
void solve(){
ll ans=;
memset(tr,,sizeof(tr));
for (int i=;i<=n;i++) b[i]=(b[i-]+get(n-a[i]+))%tt,put(n-a[i]+,);
memset(tr,,sizeof(tr));
memset(used,true,sizeof(used));
for (int i=;i<=n;i++) put(i,);
for (int i=;i<=n;i++){
if (i!=) put(a[i-],-),used[a[i-]]=false;
for (int j=;j<a[i];j++) if (used[j]){
ll tmp=b[i-];for (int k=;k<i;k++) tmp=(tmp+get(a[k]))%tt;
if (j!=) tmp=(tmp+get(j-))%tt;
tmp=((tmp*w[n-i])+p[n-i])%tt;
ans=(ans+tmp)%tt;
}
}
cout<<ans<<endl;
}
int main(){
build();
while (cin>>n){
for (int i=;i<=n;i++) scanf("%d",a+i);
solve();
}
return ;
}

  


  浓浓的数学味...于是又得去补充几个知识了呢

  首先带取模的组合数是不能直接求解的...因为一旦C(n,m)中假设n>模数p,n!中就会出现p这个因子

  然后C(n,m)就不可避地计算出了0...

  这个时候要用到Lucas定理,递归定义  

 ll lucas(int n,int m){
if (m==) return ;
if (n<tt&&m<tt) return c(n,m);
return lucas(n/tt,m/tt)*lucas(n%tt,m%tt)%tt;
}

  另一个就是连续的组合数快速求解...

  刚开始我一直在寻找同一行之间的关系..因为毕竟之前如果是整行是可以直接算的

  然而实际上列存在着一定的关系

  我们考虑这样一列上连续一段的求解(如图中红色部分)  

  根据杨辉三角的构造方法,C(n,m)=C(n-1,m)+C(n-1,m-1)

  我们设4号格子的位置为(i,a)

  最顶端红色格子的位置为(i,b)

  C(a+1,i+1)=C(a,i)+C(a,i+1) → C(a,i)=C(a+1,i+1)-C(a,i+1)

  显然...sigma(C(i,j))(a<=j<=b)=C(a+1,i+1)-C(b,i+1)

  在图中也就是橙色格子-蓝色格子

  然后对于每一列求解就可以了,但是要注意可能a,b不是真正的a,b

  因为我们现在考虑的是建立在红色部分都至少为1的基础上的,于是对于每一列都要对行标号进行处理

  另外还要注意,即使实际代表意义上不可能但取模意义下的减法可能会减出负的,也要处理

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#define maxn 100010
#define ll long long
int x1,y1,x2,y2,tt;
ll fac[maxn],inv[maxn];
int max(int a,int b){
if (a>b) return a;
return b;
}
ll mul(ll a,ll b){
ll ans=,w=a;
while (b){
if (b%==) ans=ans*w%tt;
w=w*w%tt;b=b>>;
}
return ans;
}
void build(){
fac[]=;for (int i=;i<maxn;i++) fac[i]=fac[i-]*i%tt;
inv[]=;for (int i=;i<maxn;i++) inv[i]=mul(fac[i],tt-);
}
ll c(int n,int m){
return fac[n]*inv[m]%tt*inv[n-m]%tt;
}
ll lucas(int n,int m){
if (m==) return ;
if (n<tt&&m<tt) return c(n,m);
return lucas(n/tt,m/tt)*lucas(n%tt,m%tt)%tt;
}
ll query(int n,int m){
if (n<m) return ;
return lucas(n,m);
}
void solve(){
ll ans=;
for (int i=y1;i<=y2;i++) {
if (x2<i) continue;
int l=max(x1,i),r=x2;
if (l==i){l++;ans=(ans+)%tt;}
ans=(ans+query(r+,i+)-query(l,i+)+tt)%tt;
}
printf("%lld\n",ans);
}
int main(){
while (scanf("%d",&x1)!=EOF){
scanf("%d%d%d%d",&y1,&x2,&y2,&tt);
build();
solve();
}
return ;
}

  

												

BestCoder Round #40 解题报告的更多相关文章

  1. BestCoder Round #86 解题报告

    A.Price List Sol 求和查询 Code #include<cstdio> #include<algorithm> #include<iostream> ...

  2. BestCoder Round #75 解题报告

    King's Cake [思路] 递推 公式:f(n,m)=f(max(m,n-m),min(m,n-m))+1,n>m [代码] #include<cstdio> #include ...

  3. BestCoder Round #76 解题报告

    DZY Loves Partition [思路] 贪心 [代码] #include <iostream> using namespace std; typedef long long ll ...

  4. BestCoder Round #39 解题报告

    现场只做出前三题w 不过不管怎样这既是第一次认真打BC 又是第一次体验用在线编译器调代码 订正最后一题花了今天一整个下午(呜呜 收获还是比较大的^_^ Delete wld有n个数(a1,a2,... ...

  5. 浙江省队选拔 ZJOI2015 (Round 1) 解题报告

    最近莫名其妙地喜欢上了用这种格式写各省省选的全套题解= = 今年浙江省选的出题人是算法竞赛界传说级人物陈立杰,看样子他的出题风格很有特点……ABC三题难度是严格递减的,感觉如果在做第一题的时候被卡住的 ...

  6. Codeforces Round #300 解题报告

    呜呜周日的时候手感一直很好 代码一般都是一遍过编译一遍过样例 做CF的时候前三题也都是一遍过Pretest没想着去检查... 期间姐姐提醒说有Announcement也自信不去看 呜呜然后就FST了 ...

  7. BestCoder Round #40

    T1:Tom and pape (hdu 5224) 题目大意: 给出一个矩形面积N,求周长的最小值.(长&&宽&&面积都是正整数) N<=109 题解: 没啥好 ...

  8. Mango Weekly Training Round #6 解题报告

    比赛链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41856#overview A.多种解法.可以dfs倒序染色,如mathlove ...

  9. Mango Weekly Training Round #3 解题报告

    A. Codeforces 92A Chips 签到题.. #include <iostream> #include <cstdio> #include <cstring ...

随机推荐

  1. 第11章 认识和学习bash

    认识bash这个shell 硬件.内核和shell 用户操作计算机流程如下: 用户——>用户界面(shell,KDE,application)——>核心(kernel)——>硬件(h ...

  2. Spring Boot(八)集成Spring Cache 和 Redis

    在Spring Boot中添加spring-boot-starter-data-redis依赖: <dependency> <groupId>org.springframewo ...

  3. eclipse取消validation验证

    点击按钮如下:window-Preferences-Validation.如图. 然后把build里面的都取消.即可.

  4. Struts2(二)

    以下内容是基于导入struts2-2.3.32.jar包来讲的 1.关于StrutsPrepareAndExecuteFilter 启动StrutsPrepareAndExecuteFilter时加载 ...

  5. 【C】树

    1.子树是不相交的 2.除了根节点,每个节点有且仅有一个父节点 3.一颗n个节点的树有n-1条边 儿子兄弟表示法 满二叉树与完全二叉树 1.满二叉树是除了叶子节点,每一个节点都有两个子节点,并按顺序排 ...

  6. redis 同步化操作

    异步化操作是很麻烦的的.不好控.下面介绍个同步化的库bluebird.用法很简单.看下你还子就知道了 const redis = require('redis'); const bluebird = ...

  7. js & array to string

    js & array to string https://stackoverflow.com/questions/13272406/convert-string-with-commas-to- ...

  8. BZOJ 1177 Oil(特技枚举)

    对于三个正方形的位置一共有六种情况. 预处理出(i,j)左上角,左下角,右上角,右下角区域内最大权值的正方形. 枚举分界线更新答案. 刚开始想了一个错误的DP也是蠢啊. #include<set ...

  9. mysql索引长度的一些限制

    一.myisam存储引擎 1. 数据库版本:阿里云RDS MySQL5.1 mysql> select @@version;+-------------------------------+| ...

  10. [HNOI2011]XOR和路径 概率期望 高斯消元

    题面 题解:因为异或不太好处理,,,因此按位来算,这样最后的答案就是每一位上的值乘对应的权值再求和.本着期望要倒退的原则,,,我们设$f[i]$表示从$i$到$n$,xor和为1的概率.那么观察$xo ...