【每日一题】逆序对
逆序对
http://www.nowcoder.com/questionTerminal/1e3eb598c8ca4631ae2f9ce9016470ec
1. 算出前几项然后OEIS
2. 组合数学
从低位到高位选择0或者1填数,当填到第i位的时候,如果第i位为0对答案是没有贡献的,如果是1就要算前面已经填好的长度为i-1的串中有多少个0,因此计算每一个位置为1时的贡献的和就是答案;
当字符串的第i位为1时,它对答案的贡献就是长度为i-1的串的0的个数,所有长度为i-1的串一共有(i-1) * 2^(i-1)个数字,0的个数和1的个数应该一样,0应该有(i-1) * 2^(i-2)个;而填好第i位后,后面还有n-i个位置没填完,还有2^(n-i)种方式填好整个长度为n字符串,当字符串第i为1时的贡献是(i-1) * 2^(i-2) * 2^(n-i) = (i-1) * 2^(n-2);
对n个位置的贡献求和可得n * (n-1)*2^(n-2)
#include <cstdio> using namespace std; typedef long long ll; const ll mod = 1e9+7; ll qpow(ll a,ll n){ ll res = 1; while(n){ if(n&1) res = res*a%mod; a = a*a%mod; n>>=1; } return res%mod; } ll n; int main(){ scanf("%lld",&n); n--; ll ans = (n%mod)*((n+1)%mod)%mod; ans = ans*qpow(2,n-2)%mod; printf("%lld\n",ans); return 0; }