这场是第一场没有米的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. Java 静态代码块&构造代码块&局部代码块

    /* 静态代码块. 随着类的加载而执行.而且只执行一次. 作用: 用于给类进行初始化. */ class StaticCode { static int num ; static { num = 10 ...

  2. 201621123037 《Java学习设计》 第五周学习总结

    Week05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键词:接口."has-a".多态.comparable.Compa ...

  3. 【beta】nice!-------约吧NABCD

    小组名称:nice! 组长:李权 成员:于淼  刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 约吧APP下载地址: 百度云:链接:http://pan.baidu.com/s/1jHNBR3g ...

  4. maven 添加tomcat依赖

    https://my.oschina.net/angel243/blog/178554

  5. Win server 2016 升级 Win server 2019 [测试验证]

    . 给win server 2016 挂在 win server 2019 的安装盘 2. 点击setup 直接进行安装操作  选择不下载更新, 然后到达输入序列号的界面 序列号为: WMDGN-G9 ...

  6. gridview 第一行编辑

    <%@ Page Language="C#" AutoEventWireup="true" Codebehind="Default.aspx.c ...

  7. Linux下objdump查看C程序编译后的汇编代码

    http://m.blog.csdn.net/article/details?id=47747047 Uboot中start.S源码的指令级的详尽解析 http://www.crifan.com/fi ...

  8. java 类型转型

  9. ans_rproxy 说明

    ans_rproxy 说明 网络IP资源分配 Windows2008R2:        IP: 172.16.204.50/24        Gateway: 172.16.204.1      ...

  10. 【刷题】BZOJ 3172 [Tjoi2013]单词

    Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N ...