zoukankan      html  css  js  c++  java
  • bzoj4869

    http://www.lydsy.com/JudgeOnline/problem.php?id=4869

    终于A了。。。参考了下dalao的代码。。。

    拓展欧几里得定理,改了几次就不变了,但是用的时候要在快速幂里判是不是要用。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 100010;
    int n, m, cnt;
    ll p, c;
    ll phi[N], table[N];
    namespace seg // n^x = n^(x % phi[x] + phi[x])
    {
        struct data {
            ll ans, mn;
        } tree[N << 2];
        inline ll getphi(ll x)
        {
            ll ret = x, lim = x;
            for(ll i = 2; i * i <= lim; ++i) if(x % i == 0) 
            {
                ret = ret * (i - 1) / i;
                while(x % i == 0) x /= i;
            }
    //      printf("ret=%d
    ", ret);
            if(x > 1) ret = ret * (x - 1) / x;
            return ret;
        }
        inline ll power(ll x, ll t, ll p, bool &flag)
        {
            bool big = false;
            ll ret = 1; 
            for(; t; t >>= 1) 
            {
                if(t & 1) 
                {
                    ret = ret * x ;
                    flag |= big | (ret >= p);        
                    ret %= p;
                }
                x = x * x; if(x >= p) big = true, x %= p; 
            }
            return ret; 
        }
        ll calc(ll x, int t)
        {
            if(x >= phi[t]) x = x % phi[t] + phi[t];
            for(int i = t - 1; i >= 0; --i) 
            {
                bool flag = false;
                x = power(c, x, phi[i], flag);
                if(flag) x += phi[i];
            }
            return x % phi[0];
        }
        inline void build(int l, int r, int x)
        {
            if(l == r) { 
                tree[x].ans = table[l]; 
                return; 
            }
            int mid = (l + r) >> 1;
            build(l, mid, x << 1); 
            build(mid + 1, r, x << 1 | 1);
            tree[x].ans = (tree[x << 1].ans 
                         + tree[x << 1 | 1].ans) % phi[0];
        } 
        inline void update(int l, int r, int x, int a, int b)
        { //如果这次的幂和上次一样就不变了 
            if(tree[x].mn >= cnt) return;
            if(l > b || r < a) return;
            if(l == r)
            {
                ++tree[x].mn;
                tree[x].ans = calc(table[l], tree[x].mn);
                return;
            }
            int mid = (l + r) >> 1;
            update(l, mid, x << 1, a, b); 
            update(mid + 1, r, x << 1 | 1, a, b);
            tree[x].mn = min(tree[x << 1].mn, 
                             tree[x << 1 | 1].mn);
            tree[x].ans = (tree[x << 1].ans + 
                           tree[x << 1 | 1].ans) % phi[0]; 
        }
        inline ll query(int l, int r, int x, int a, int b)
        {
            if(l > b || r < a) return 0;
            if(l >= a && r <= b) return tree[x].ans % phi[0];
            int mid = (l + r) >> 1, ret = 0;
            ret = (ret + query(l, mid, x << 1, a, b)) % phi[0];
            ret = (ret + query(mid + 1, r, x << 1 | 1, a, b)) % phi[0];
            return ret;    
        } 
    } using namespace seg;
    int main()
    {
        scanf("%d%d%lld%lld", &n, &m, &p, &c);
        phi[0] = p;
        ll P = p;
        while(P != 1) phi[++cnt] = P = getphi(P);
        phi[++cnt] = 1; 
        for(int i = 1; i <= n; ++i) scanf("%lld", &table[i]);
        build(1, n, 1); 
        while(m--)
        {
            int opt, l, r; scanf("%d", &opt);
            if(opt == 0)
            {
                scanf("%d%d", &l, &r); 
                update(1, n, 1, l, r);
            }
            if(opt == 1) 
            {
                scanf("%d%d", &l, &r);
                printf("%lld
    ", query(1, n, 1, l, r));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    UVa 1451 Average (斜率优化)
    POJ 1160 Post Office (四边形不等式优化DP)
    HDU 3507 Print Article (斜率DP)
    LightOJ 1427 Substring Frequency (II) (AC自动机)
    UVa 10245 The Closest Pair Problem (分治)
    POJ 1741 Tree (树分治)
    HDU 3487 Play with Chain (Splay)
    POJ 2828 Buy Tickets (线段树)
    HDU 3723 Delta Wave (高精度+calelan数)
    UVa 1625 Color Length (DP)
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6832433.html
Copyright © 2011-2022 走看看