zoukankan      html  css  js  c++  java
  • 【魔改】莫队算法+组合数公式 杭电多校赛4 Problem B. Harvest of Apples

    http://acm.hdu.edu.cn/showproblem.php?pid=6333

    莫队算法是一个离线区间分块瞎搞算法,只要满足:1.离线  2.可以O(1)从区间(L,R)更新到(L±1,R±1)就能直接套板子了

    这道题不是区间算法,但是有递推式:

    把它看成区间更新orz

    所以可以莫队orz

    #define _CRT_SECURE_NO_WARNINGS
    #include    <cmath>
    #include <iostream>
    #include    <stdio.h>
    #include<algorithm>
    #include        <map>
    #include     <cstring>
    #include      <time.h>
    using namespace std;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    const int maxn = 1e5 + 5;
    const long long mod = 1e9 + 7;
    map<int, int> mmp;
    typedef long long ll;
    struct node {
        int l, r, id;
    
    }Q[maxn];
    ll fac[maxn], infac[maxn];
    long long ans[maxn];
    long long num[maxn];
    int a[maxn], pos[maxn];
    int n, m, k;
    int L = 1, R = 0;
    long long Ans = 0;
    
    ll cal(ll x) {
        ll res = 1;
        int k = mod - 2;
        while (k) {
            if (k & 1) {
                res *= x;
                res %= mod;
            }
            x *= x;
            x %= mod;
            k >>= 1;
        }
        return res;//cal(x^ mod)
    }
    void init() {
        fac[0] = 1;
        rep(i, 1, maxn - 1)fac[i] = (fac[i-1] * i)%mod;
        rep(i, 0, maxn - 1)infac[i] = cal(fac[i]);
    }
    ll C(ll a, ll b)
    {
        return 1ll * fac[a] * infac[b] % mod * infac[a - b] % mod;
    }
    bool cmp(node a, node b) {
        if (pos[a.r] == pos[b.r])
            return a.l < b.l;
        return pos[a.r] < pos[b.r];
    
    }
    void add(int x) {
    
        //num[a[x]]++;
        //if (num[a[x] - 1] == 0 && num[a[x] + 1] == 0)Ans++;
        //else if (num[a[x] - 1] && num[a[x] + 1])Ans--;
        Ans += C(n, m);
    
    }
    void addl(int x) {
    
    }
    void del(int x) {
        //num[a[x]]--;
        //if (num[a[x] - 1] == 0 && num[a[x] + 1] == 0)Ans--;
        //else if (num[a[x] - 1] && num[a[x] + 1])Ans++;
        Ans -= C(n, m + 1);
    }
    
    int smain() {
        int t; scanf("%d", &t);
        init();
            Ans = 0;
            mmm(num, 0);
            L = 1, R = 0;
            
            int sz = sqrt(1e5);
            for (int i = 1; i <= 1e5; i++) {
                pos[i] = i / sz;
            }
    
            rep(i,1,t) {
                scanf("%d%d", &Q[i].l, &Q[i].r);
                Q[i].id = i;
            }
            sort(Q + 1, Q + 1 + t, cmp);
            Ans = 0;//S(m,n
            L = Q[1].l; R = -1;
            rep(i,1,t){
                while (L < Q[i].l) {
                    //del(L);
                    Ans = (2ll * Ans - C(L, R) + mod) % mod;
                    ++L;
                }
    
                while (L > Q[i].l) {
                    --L;
                    //addl(L);
                    Ans = ((Ans + C(L, R)) *infac[2]%mod) % mod;
                }
    
    
                while (R < Q[i].r) {
                    ++R;
                    //add(R);
                    Ans = (Ans+C(L, R))%mod;
                }
                while (R > Q[i].r) {
                    //del(R);
                    Ans = (Ans-C(L, R)+mod)%mod;
                    --R;
    
                }
                
                ans[Q[i].id] = Ans;
            }
            rep(i,1,t)printf("%lld
    ", ans[i]);
        return 0;
    }
    /*
    
    
    6
    60522 25373
    36426 3283
    48772 42553
    33447 12441
    3497 2182
    7775 4025
    
    */
    #define ONLINE_JUDGE
    int main() {
        //ios::sync_with_stdio(false);
    #ifndef ONLINE_JUDGE
        FILE *myfile;
        myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
        if (myfile == NULL)
            fprintf(stdout, "error on input freopen
    ");
        FILE *outfile;
        outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
        if (outfile == NULL)
            fprintf(stdout, "error on output freopen
    ");
        long _begin_time = clock();
    #endif
        smain();
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
        cin >> n;
        return 0;
    }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    列表
    Lambda表达式
    委托
    泛型(二)
    泛型(一)
    继承
    object类
    linux 命令补全包
    记一次 mysql 安装完成后启动报错 且 日志为空
    nginx 下配置https 访问提示下载文件 解决方法
  • 原文地址:https://www.cnblogs.com/SuuT/p/9418157.html
Copyright © 2011-2022 走看看