zoukankan      html  css  js  c++  java
  • 51nod 最近刷题 简要题解

    51nod 1564

    由于数据是随机的,可以证明,对于每一个数,向左或右找比它小的数,长度是logn级别的

    考虑枚举最大值

    注意,对于每一个最大值,如果直接用2个循环枚举左右端点的话,理论是lognlogn级别的,但是还是很容易被卡的,换成贪心,用2个指针指着左右端点,每一次移动我们往数大的那个方向移动

    代码:

                                                
      //File Name: nod1564.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月10日 星期一 19时59分32秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #define LL long long
    using namespace std;
    const int MAXN = 100000 + 5;
    const LL INF = (1<<18);
    LL a[MAXN],ans[MAXN];
    int l[MAXN],r[MAXN];
    void solve(int n){
        l[1] = 1;
        for(int i=2;i<=n;i++){
            l[i] = i;
            while(l[i] > 1 && a[l[i]-1] <= a[i])
                l[i] = l[l[i]-1];
        }
        r[n] = n;
        for(int i=n-1;i>0;i--){
            r[i] = i;
            while(r[i] < n && a[r[i]+1] < a[i])
                r[i] = r[r[i]+1];
        }
        memset(ans,0,sizeof ans);
        for(int i=1;i<=n;i++){
            LL mi1 = a[i];
    /*
            for(int j=i;j>=l[i];j--){
                mi1 = min(mi1,a[j]);
                LL mi2 = mi1;
                for(int k=i;k<=r[i];k++){
                    mi2 = min(mi2,a[k]);
                    ans[k-j+1] = max(ans[k-j+1],a[i] * mi2);
                }
            }
    */
            int j = i,k = i;
            while(true){
                ans[k-j+1] = max(ans[k-j+1],mi1 * a[i]);
                if(j == l[i] && k == r[i]) break;
                else if(j == l[i] && k < r[i])
                    k+=1,mi1 = min(mi1,a[k]);
                else if(j > l[i] && k == r[i])
                    j-=1,mi1 = min(mi1,a[j]);
                else{
                    if(a[j-1] >= a[k+1])
                        j-=1,mi1 = min(mi1,a[j]);
                    else
                        k+=1,mi1 = min(mi1,a[k]);
                }
            }
        }
        for(int i=n-1;i>=1;i--)
            ans[i] = max(ans[i],ans[i+1]);
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",a + i);
        solve(n);
        for(int i=1;i<=n;i++)
            printf("%lld
    ",ans[i]);
        return 0;
    }
    View Code

    51nod 1375

    给出n个数,问从中找出刚好k个数或者任意个数,使得这些数的gcd = 1的方案数

    枚举gcd,mobius反演下就可以了

    代码:

                                                
      //File Name: nod1375.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月10日 星期一 13时28分47秒
                                       
    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <string.h>
    #define LL long long
    using namespace std;
    const int MOD = 998244353;
    const int MAXN = 1000000 + 1;
    const int N = 100000 + 1;
    int s[MAXN],K;
    int mu[MAXN],prime[MAXN];
    bool check[MAXN];
    LL p2[N],jie[N];
    LL qp(LL x,LL y){
        LL res = 1;
        for(;y>0;y>>=1){
            if(y & 1) res = res * x % MOD;
            x = x * x % MOD;
        }
        return res;
    }
    LL C(LL x,LL y){
        if(y < 0 || y > x) return 0;
        if(y == 0 || y == x) return 1;
        return jie[x] * qp(jie[y] * jie[x-y] % MOD,MOD - 2) % MOD;
    }
    void mobius(){
        memset(check,false,sizeof check);
        mu[1] = 1;
        int tot = 0;
        for(int i=2;i<MAXN;i++){
            if(!check[i]){
                prime[tot++] = i;
                mu[i] = -1;
            }
            for(int j=0;j<tot;j++){
                if(i * prime[j] >= MAXN) break;
                check[i * prime[j]] = true;
                if(i % prime[j] == 0){
                    mu[i * prime[j]] = 0;
                    break;
                }
                else{
                    mu[i * prime[j]] = -mu[i];
                }
            }
        }
    }
    void init(){
        p2[0] = jie[0] = 1;
        for(int i=1;i<N;i++){
            p2[i] = p2[i-1] * 2 % MOD;
            jie[i] = jie[i-1] * i % MOD;
        }
        mobius();
    }
    LL cal(int sum){
        if(K == -1) return p2[sum] - 1;
        return C(sum,K);
    }
    LL solve(int n,int ma){
        LL ans = 0;
        for(int k=1;k<=ma;k++){
            int sum = 0;
            for(int i=k;i<=ma;i+=k)
                sum += s[i];
            ans = (ans + mu[k] * cal(sum) + MOD) % MOD;
        }
        return ans;
    }
    int main(){
        init();
        int n,ma = 0;
        scanf("%d %d",&n,&K);
        for(int i=0,u;i<n;i++){
            scanf("%d",&u);
            ma = max(ma,u);
            s[u]++;
        }
        printf("%lld
    ",solve(n,ma));
        return 0;
    }
    View Code

    51nod 1269

    简单容斥,求组合数的时候C(n,m) % p,虽然n是10^16级别的,但是p是素数,m才20左右,直接暴力求就可以了

                                                
      //File Name: nod1269.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月10日 星期一 13时11分23秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #define LL long long
    using namespace std;
    const int MOD = (int)1e9 + 7;
    int inv[20];
    LL a[20];
    LL qp(LL x,LL y){
        LL res = 1;
        for(;y>0;y>>=1){
            if(y & 1) res = res * x % MOD;
            x = x * x % MOD;
        }
        return res;
    }
    LL C(LL x,LL y){
        if(x < y || y < 0) return 0;
        if(y == x || y == 0) return 1;
        LL ans = 1;
        for(int i=0;i<y;i++){
            ans = (x - i) % MOD * inv[y - i] % MOD * ans % MOD;
        }
    //    printf("x = %lld y = %lld ans = %lld
    ",x,y,ans);
        return ans;
    }
    LL solve(int n,LL s){
        for(int i=1;i<n;i++) 
            inv[i] = qp(i,MOD - 2);
        LL ans = 0;
        for(int i=0;i<(1<<n);i++){
            LL now = 0;
            int num = 0;
            for(int j=0;j<n;j++){
                if(i & (1 << j)){
                    num++;
                    now += a[j] + 1;
                }
            }
            
            LL tmp = C(s - now + n -1,n - 1);
            if(num & 1) ans = (ans - tmp + MOD) % MOD;
            else ans = (ans + tmp) % MOD;
        }
        return ans;
    }
    int main(){
        LL s;
        int n;
        scanf("%d %lld",&n,&s);
        for(int i=0;i<n;i++) scanf("%lld",a + i);
        cout << solve(n,s) << endl;
        return 0;
    }
    View Code

    51nod  1407

    i表示集合的状态

    f(i)表示i & x= i的x的个数,即i是x的子集

    可以分治求f

    然后容斥下就可以

                                                
      //File Name: nod1407.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月09日 星期日 22时04分55秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #define LL long long
    using namespace std;
    const int MAXN = 1 << 20;
    const int MOD = (int)1e9 + 7;
    int f[MAXN];
    LL p2[MAXN];
    void init(){
        p2[0] = 1;
        for(int i=1;i<MAXN;i++)
            p2[i] = p2[i-1] * 2 % MOD;
    }
    void cal(int pre,int i){
        if(i < 0) return ;
        cal(pre,i-1);
        cal(pre+(1<<i),i-1);
        for(int j=0;j<(1<<i);j++)
            (f[pre+j] += f[pre+(1<<i)+j] )%=MOD;
    }
    LL solve(int n){
        cal(0,19);
    //    for(int i=0;i<=10;i++)
    //        cout << f[i] << endl;
        LL ans = 0;
        for(int i=0,s;i<(1<<20);i++){
            s = 0;
            for(int j=0;j<20;j++)
                if(i & (1<<j)) s++;
            LL tmp = (p2[f[i]] - 1 + MOD) % MOD;
            if(s & 1) ans = (ans - tmp + MOD) % MOD;
            else ans = (ans + tmp) % MOD;
        }
        return ans;
    }
    int main(){
        init();
        int n;
        scanf("%d",&n);
        for(int i=0,a;i<n;i++){
            scanf("%d",&a);
            f[a]++;
        }
        cout << solve(n) << endl;
        return 0;
    }
    View Code

    51nod 1406

    与上一道题一样

                                                
      //File Name: nod1406.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月09日 星期日 11时53分29秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int f[1<<20];
    void solve(int pre,int i){
        if(i < 0) return ;
        solve(pre,i-1);
        solve(pre+(1<<i),i-1);
        for(int j=0;j<(1<<i);j++)
            f[pre+j] += f[pre+(1<<i)+j];
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=0,u;i<n;i++){
            scanf("%d",&u);
            f[u]++;
        }
        solve(0,19);
        for(int i=0;i<=1000000;i++)
            printf("%d
    ",f[i]);
        return 0;
    }
    View Code

    51nod  1362

    枚举向右下方走的次数,可以得到公式

    对于公式,有一问题,就是要求的是C(n,m)%p,这个时候p也可能是合数,n是10^9级别,但是m是1000级别的

    注意到需要消除的数都是与p的gcd大于1的,所以只需要考虑p的质因子,将与p互质的部分直接求逆元计算,不互质的部分维护成质因子的幂次,从分子中减去即可。

    O(nlogp)级别

                                                
      //File Name: nod1362.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月09日 星期日 19时14分21秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #define LL long long
    using namespace std;
    vector<int> dive;
    int s[50];
    LL mod;
    LL qp(LL x,LL y){
        LL res = 1;
        for(;y>0;y>>=1){
            if(y & 1) res = res * x % mod;
            x = x * x % mod;
        }
        return res;
    }
    LL ext_gcd(LL a,LL b,LL &x,LL &y){
        if(a == 0 && b == 0) return -1;
        if(b == 0){x = 1;y = 0;return a;}
        LL d = ext_gcd(b,a%b,y,x);
        y -= a / b * x;
        return d;
    }
    LL inv(LL a,LL n){
        LL x,y;
        LL d = ext_gcd(a,n,x,y);
        if(d == 1) return (x % n + n) % n;
        return -2;
    }
    void cal_dive(LL p){
        dive.clear();
        for(int i=2;i*i<=p;i++){
            if(p % i == 0){
                dive.push_back(i);
                while(p % i == 0) p /= i;
            }
        }
        if(p > 1) dive.push_back(p);
        sort(dive.begin(),dive.end());
    }
    LL fact(LL x,int f){
        for(int i=0;i<dive.size();i++){
            while(x % dive[i] == 0){
                s[i]+=f;
                x /= dive[i];
            }
        }
        if(f == -1) return inv(x,mod);
        return x;
    }
    LL cal(LL l,LL r,LL a,LL b,LL c){
        memset(s,0,sizeof s);
        LL ans = fact(a,-1);
        for(int i=2;i<=b;i++)
            ans = ans * fact(i,-1) % mod;
        for(int i=2;i<=c;i++)
            ans = ans * fact(i,-1) % mod;
        for(LL i=l;i<=r;i++)
            ans = ans * fact(i,1) % mod;
        for(int i=0;i<dive.size();i++){
            ans = ans * qp(dive[i],s[i]) % mod;
        }
        return ans;
    }
    LL solve(LL n,LL m){
        LL ans = 0;
        LL ma = min(n,m);
        cal_dive(mod);
        for(int c=0;c<=ma;c++){
            ans = (ans + cal(m-c+1,m-c+1+n,n+1,c,n-c)) % mod;
        }
        return ans;
    }
    int main(){
        LL n,m;
        cin >> n >> m >> mod;
        cout << solve(n,m) << endl;
        return 0;
    }
    View Code

    51nod 1197

    由于每次跳跃都是*2的,字符串实际上可以划分成若干条链的组合,每一条链都是logn长度的

    再加个矩阵乘法

                                                
      //File Name: nod1197.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月08日 星期六 20时18分58秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #define LL long long
    using namespace std;
    const int MAXN = 1000000 + 2;
    const int MOD = (int)1e9 + 7;
    const int N = 22;
    int f[MAXN][N],len[N],g[N];
    struct matrix_t{
        LL x[N][N];
        matrix_t(int v){
            memset(x,0,sizeof(x));
            for(int i=1;i<=N;i++) x[i][i] = v;
        }
        matrix_t operator*(const matrix_t &r){
            matrix_t p(0);
            for(int k=1;k<=N;k++){
                for(int i=1;i<=N;i++){
                    if(x[i][k] == 0) continue;
                    for(int j=1;j<=N;j++){
                        p.x[i][j] += x[i][k] * r.x[k][j] % MOD;
                        p.x[i][j] %= MOD;
                    }
                }
            }
            return p;
        }
        matrix_t power(LL p){
            matrix_t r(1),a = *this;
            for(;p;p>>=1){
                if(p & 1) r = r * a;
                a = a * a;
            }
            return r;
        }
    };
    LL solve(int n,LL m){
        f[0][0] = 1;
        for(int i=1;i<=n;i++){
            f[i][0] = 1;
            for(int j=1;j<=20;j++)
                f[i][j] = (0LL + f[i-1][j] + f[i/2][j-1]) % MOD;
        }
        for(int i=1;i<=20;i++)
            len[i] = (0LL + f[n][i] - f[n/2][i] + MOD) % MOD;
        matrix_t mat(0);
        for(int i=1;i<=20;i++)
            mat.x[1][i] = len[i];
        for(int i=2;i<=21;i++)
            mat.x[i][i-1] = 1;
        g[0] = 1;
        for(int i=1;i<N;i++)
            for(int j=1;j<=20 && j <= i;j++)
                g[i] = (0LL + g[i] + 1LL * g[i-j] * len[j] % MOD) % MOD;    
        if(m < N) return g[m];
        mat = mat.power(m - 21);
        LL ans = 0;
        for(int i=1;i<N;i++)
            ans = (0LL + ans + mat.x[1][i] * g[N - i] % MOD) % MOD;
        return ans;
    }
    int main(){
        int n;
        LL m;
        cin >> n >> m;
        cout << solve(n,m) <<endl;
        return 0;
    }
    View Code

    51nod 1251

    枚举出现最大频率的那个频率,对于剩下的容斥就可以,发现对于枚举i,后面的复杂度是n/i

    所以n / 1 + n / 2 + n / 3 + ... = O(nlogn)

                                                
      //File Name: nod1251.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月08日 星期六 14时39分39秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    using namespace std;
    const int MAXN = 200000 + 10;
    const int MOD = (int)1e9 + 7;
    LL jie[MAXN],inv[MAXN];
    LL qp(LL x,LL y){
        LL res = 1;
        for(;y;y>>=1){
            if(y & 1) res = res * x % MOD;
            x =x * x % MOD;
        }
        return res;
    }
    void init(){
        jie[0] = 1;
        for(int i=1;i<MAXN;i++)
            jie[i] = jie[i-1] * i % MOD;
        for(int i=0;i<MAXN;i++)
            inv[i] = qp(jie[i],MOD - 2);
    }
    LL solve(int n,int m){
        if(m == 1) return 1;
        LL ans = 0,tmp;
        for(int i=1,ma;i<=n;i++){
            ma = (n - i) / i;
            for(int j=0;j<=ma;j++){
                if(m - 1 < j) continue;
                tmp = jie[n-(j+1)*i+m-2]*inv[m-2]%MOD*inv[n-(j+1)*i]%MOD;
                tmp = tmp*jie[m-1]%MOD*inv[j]%MOD*inv[m-1-j]%MOD;
                if(j & 1) ans = (ans - tmp + MOD) % MOD;
                else ans = (ans + tmp) % MOD;
            }
        }
        return ans * m % MOD;
    }
    int main(){
        init();
        int t;
        scanf("%d",&t);
        while(t--){
            int n,m;
            scanf("%d %d",&n,&m);
            printf("%lld
    ",solve(n,m));
        }
        return 0;
    }
    View Code

    51nod 1668

    推下dp公式,矩阵乘法

                                                
      //File Name: nod1668.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月04日 星期二 16时04分05秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #define LL long long
    using namespace std;
    const int N = 4;
    const int MOD = (int)1e9 + 7;
    int g[5];
    struct matrix_t{
        LL x[N+1][N+1];
        matrix_t(int v = 1){
            memset(x,0,sizeof x);
            for(int i=1;i<=N;i++) x[i][i] = v;
        }
        matrix_t operator*(const matrix_t &r){
            matrix_t p(0);
            for(int k=1;k<=N;k++){
                for(int i=1;i<=N;i++){
                    if(x[i][k] == 0) continue;
                    for(int j=1;j<=N;j++){
                        (p.x[i][j] += x[i][k] * r.x[k][j] % MOD) %= MOD;
                    }
                }
            }
            return p;
        }
        matrix_t power(LL p){
            matrix_t r(1),a = *this;
            for(;p;p>>=1){
                if(p & 1) r = r * a;
                a = a * a;
            }
            return r;
        }
    };
    LL solve(LL n){
        g[1] = 2,g[2] = 4,g[3] = 7,g[4] = 12;
        if(n <= 4) return g[n];
        matrix_t mat(0);
        mat.x[1][1] = mat.x[1][2] = mat.x[1][4] = 1;
        mat.x[2][1] = mat.x[3][2] = mat.x[4][3] = 1;
        mat = mat.power(n - 4);
        LL ans = mat.x[1][1] * g[4] % MOD + mat.x[1][2] * g[3] % MOD + 
            mat.x[1][3] * g[2] % MOD + mat.x[1][4] * g[1] % MOD;
        return ans % MOD;
    }
    int main(){
        LL n;
        cin >> n;
        cout << solve(n) << endl;
        return 0;
    }
    View Code

    51nod 1309

    求出a中不同的排列有P种

    考虑每个数ai会在哪些排列中产生贡献,设a中比M大的数有k个,一个小于等于M的数ai能产生贡献当且仅当ai在排列中的位置在这k个数之前,即对于这k+1个数,ai的位置在最前,由于ai 与这k个数都不相同,这样的概率是1 / (k+1) ,所以ai可以产生贡献的排列有P / (k+1)  个,设a中 <= M 的数的和是S,则答案是

    S * P / (k + 1)

    先统计出来,对于每一个询问,2分得到答案

                                                
      //File Name: nod1309.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月05日 星期三 13时22分11秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #include <map>
    #define LL long long
    #define fir first
    #define sec second
    using namespace std;
    const int MAXN = 50010;
    const int MOD = (int)1e9 + 7;
    int a[MAXN];
    map<int,LL> pre_s,ans;
    map<int,int> pre_num;
    LL P,jie[MAXN];
    LL qp(LL x,LL y){
        LL res = 1;
        for(;y>0;y>>=1){
            if(y & 1) res = res * x % MOD;
            x = x * x % MOD;
        }
        return res;
    }
    int bs(int l,int r,int x){
        if(a[l] > x) return -1;
        if(a[r] <= x) return a[r];
        while(r - l > 1){
            int mid = l + r >> 1;
            if(a[mid] <= x) l = mid;
            else r = mid;
        }
        return a[l];
    }
    void solve(int n,int q){
        jie[0] = 1;
        for(int i=1;i<MAXN;i++) jie[i] = jie[i-1] * i % MOD;
        sort(a,a+n);
        P = jie[n];
        for(int i=0;i<n;i++){
            pre_s[a[i]] += a[i];
            pre_num[a[i]]++;
        }
        for(map<int,int>::iterator it=pre_num.begin();it!=pre_num.end();it++)
            P = P * qp(jie[it->sec],MOD - 2) % MOD;
    //    cout << P << endl;
        for(map<int,int>::iterator pre=pre_num.begin(),it;pre!=pre_num.end();pre++){
            it = ++pre;
            --pre;
            if(it==pre_num.end()) break;
            pre_num[it->fir] += pre_num[pre->fir];
    //        cout << it->fir << " " << pre_num[it->fir] << endl;
        }
        for(map<int,LL>::iterator pre=pre_s.begin(),it;pre!=pre_s.end();pre++){
            it = ++pre;
            --pre;
            if(it == pre_s.end()) break;
            (pre_s[it->fir] += pre_s[pre->fir]) %= MOD;
    //        cout << it->fir << " " << pre_s[it->fir] << endl;
        }
        for(int i=0;i<n;i++){
            ans[a[i]] = pre_s[a[i]] * P % MOD * qp(n-pre_num[a[i]]+1,MOD - 2) % MOD;
    //        cout << a[i] << " " << pre_s[a[i]] << " " << n - pre_num[a[i]] + 1 <<endl;
        }
        for(int i=0,x;i<q;i++){
            scanf("%d",&x);
            x = bs(0,n-1,x);
    //        cout << x << endl;
            if(x == -1) puts("0");
            else printf("%lld
    ",ans[x]);
        }    
    }
    int main(){
        int n,q;
        scanf("%d %d",&n,&q);
        for(int i=0;i<n;i++) scanf("%d",a + i);
        solve(n,q);
        return 0;
    }
    View Code

    51nod 1667

    把甲的数字写成Li+xi的形式,乙的写成Ri-yi的形式,整理后发现,其实要求的是:

    x1 + x2 + ... + xn < S ,0 <= xi <= MAi 这种形式,S和MAi都是常数

    容斥就可以了

                                                
      //File Name: nod1667.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年10月04日 星期二 20时22分27秒
                                       
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    #define LL long long
    using namespace std;
    const int MOD = (int)1e9 + 7;
    const LL INF = 1000000000000;
    int l[20],r[20],k1,k2;
    LL A,inv[20],ma[20];
    LL qp(LL x,LL y){
        LL res = 1;
        for(;y>0;y>>=1){
            if(y & 1) res = res * x % MOD;
            x = x * x % MOD;
        }
        return res;
    }
    LL C(LL x,LL y){
        if(x < y || y < 0) return 0;
        if(y == 0 || y == x) return 1;
        LL res = 1;
        for(LL i=0;i<y;i++)
            res = res * (x - i) % MOD * inv[y-i] % MOD;
    //    cout << x << " " << y << endl;
    //    cout << res << endl;
        return res;
    }
    LL cal(int n){
        if(A < 0) return 0;
        LL res = 0,s,tmp;
        for(int i=0,num;i<(1<<n);i++){
            num = 0,s = 0;
            for(int j=0;j<n;j++){
                if(i & (1<<j)){
                    num++;
                    s += ma[j] + 1;
                }
            }
            tmp = C(A-s+n-1,n-1);
            if(num & 1) (res = res - tmp + MOD) %= MOD;
            else (res += tmp) %= MOD;
        }
    //    if(res < 0) cout << "fff " << endl;
        return res;
    }
    void solve(){
        LL ansl = 0,ansg = 0,anseq = 0,sum = 1;
        A = 0;
        for(int i=0;i<k1;i++) A -= l[i];
        for(int i=k1;i<k1+k2;i++) A += r[i];
        anseq = cal(k1+k2);
        A--;
        ansl = cal(k1+k2+1);
        A = 0;
        for(int i=0;i<k1;i++) A += r[i];
        for(int i=k1;i<k1+k2;i++) A -= l[i];
        A--;
        ansg = cal(k1+k2+1);
        for(int i=0;i<k1+k2;i++){
            sum = sum * (r[i] - l[i] + 1) % MOD;
        }
        sum = qp(sum,MOD - 2);
        ansl = ansl * sum % MOD;
        ansg = ansg * sum % MOD;
        anseq = anseq * sum % MOD;
        printf("%lld %lld %lld
    ",ansg,anseq,ansl);
    }
    int main(){
        for(int i=1;i<20;i++) inv[i] = qp(i,MOD - 2);
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&k1);
            for(int i=0;i<k1;i++)    
                scanf("%d %d",&l[i],&r[i]),ma[i] = r[i] - l[i];
            scanf("%d",&k2);
            for(int i=k1;i<k1+k2;i++)
                scanf("%d %d",&l[i],&r[i]),ma[i] = r[i] - l[i];
            ma[k1+k2] = INF;
            solve();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    nova 注入adminpass 添加用户等设置
    mysql 集群 avc error
    openstack novnc console haproxy mitaka
    NFS金陵科技学院
    windows下命令行格式化U盘
    linux下安装mysql
    连表查询
    查询语句
    索引
    插入,更新与删除数据
  • 原文地址:https://www.cnblogs.com/-maybe/p/5948366.html
Copyright © 2011-2022 走看看