【每日一题】4月16日 组合数学

逆序对

https://ac.nowcoder.com/acm/problem/14731

include<bits/stdc++.h>

using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 2e5+5;
const int M = 1e6;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a) push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
考虑任意两个位置作为1,0,构成的串的个数.
很明显当两个位置i = 1,j = 0时。
其他位置都有2种选择。那么构成的不同串数就是2222..... = 2^(n-2).
所以每一对位置都可以构成这么多串,然后把每对位置看成独立地去计算就可以了.
对于每对位置,那么就任选一对位置C(n,2).(n(n-1)/2)
注意特判n = 1,因为就会 n-2 = -1.
所以总次数就是C(n,2)
2^(n-1).
一些思考:
为什么可以将这些位置单独拿出来看呢.
因为我们其实是列举出了所有的位置情况,然后将这些位置情况里的固定一对位子的贡献求解出来。
所以事实上我们枚举的这些情况中很多都是重复的,但是对于我们固定的枚举的位置,这些形成的最后串是不一样的.
又因为他们有共性,所以我们可以得到这个结果.

LL quick_mi(LL a,LL b)
{
    LL re = 1;
    while(b)
    {
        if(b&1) re = (re*a)%Mod;
        b >>= 1;
        a = (a*a)%Mod;
    }
    return re%Mod;
}
int main()
{
    LL n;sld(n);
    LL t = (n%Mod*((n-1)%Mod)/2)%Mod;//注意这里的取模,应该先n%mod,和(n-1)%mod之后在乘.如果只n%mod*(n-1)%mod的话.n%mod*(n-1)也会爆longlong.
    if(n == 1) printf("0\n");
    else plr(t*quick_mi(2,n-2)%Mod);
    system("pause");
    return 0;
}
全部评论
突然发现头文件贴错地方了。不知道怎么修改发布的..就只能这样了..
点赞 回复 分享
发布于 2020-04-16 18:05

相关推荐

不愿透露姓名的神秘牛友
11-27 10:52
点赞 评论 收藏
分享
10-27 17:26
东北大学 Java
点赞 评论 收藏
分享
totoroyyw:千年老妖😂
投递华为等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务