zoukankan      html  css  js  c++  java
  • bzoj4402 Claris的剑

    嘟嘟嘟


    看到这道题本质不同的定义就觉得这题挺奇怪的,估计组合计数之前得有一些转化吧。
    反正我是没搞出来。


    通过打表找规律(???),发现序列无非这两种情况:
    1 2 1 2 1 2 3 2 3 2 3 4 3 4
    1 2 1 2 3 2 3 2 3 2 3 4 3
    也就是结尾可能是最大值,可能是最大值 - 1、
    这样我们枚举最大值(i),于是对于每一个序列:1.1~(i)必须出现。2.剩下的(n - i)个数,如果出现了一个(t),伴随他的必有一个(t + 1),相当于1个占2个的位置。
    也就是说,我们接下来要把(i)种数放入(lfloor frac{n - i}{2} floor)个盒子中。这个就是插板法了。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<assert.h>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 4e6 + 5;
    const ll mod = 1e9 + 7;
    In ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    In void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    In void MYFILE()
    {
    #ifndef mrclr
      freopen(".in", "r", stdin);
      freopen(".out", "w", stdout);
    #endif
    }
    
    int n, m;
    ll fac[maxn], inv[maxn];
    
    In ll inc(ll a, ll b) {return a + b < mod ? a + b : a + b - mod;}
    In ll F(int n, int m) 
    {
    	if(n < 0) return 0;
    	return fac[n + m - 1] * inv[n] % mod * inv[m - 1] % mod;
    }
    In ll quickpow(ll a, ll b)
    {
      ll ret = 1;
      for(; b; b >>= 1, a = a * a % mod)
        if(b & 1) ret = ret * a % mod;
      return ret;
    }
    
    In void init()
    {
      fac[0] = inv[0] = 1;
      for(int i = 1; i < maxn; ++i) fac[i] = fac[i - 1] * i % mod;
      inv[maxn - 1] = quickpow(fac[maxn - 1], mod - 2);
      for(int i = maxn - 2; i; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
    }
    
    int main()
    {
      //MYFILE();
      n = read(), m = read();
      init();
      ll ans = 1;
      for(int i = 2; i <= min(n, m); ++i)
        {
          ans = inc(ans, F((n - i) >> 1, i));   //情况1
          ans = inc(ans, F((n - i - 1) >> 1, i));   //情况2
        }
      write(ans), enter;
      return 0;
    }
    
  • 相关阅读:
    软件体系架构复习要点
    Operating System on Raspberry Pi 3b
    2019-2020 ICPC North-Western Russia Regional Contest
    2019 ICPC ShenYang Regional Online Contest
    2019 ICPC XuZhou Regional Online Contest
    2019 ICPC NanChang Regional Online Contest
    2019 ICPC NanJing Regional Online Contest
    Codeforces Edu Round 72 (Rated for Div. 2)
    Codeforces Round #583 (Div.1+Div.2)
    AtCoder Beginning Contest 139
  • 原文地址:https://www.cnblogs.com/mrclr/p/10934103.html
Copyright © 2011-2022 走看看