zoukankan      html  css  js  c++  java
  • bzoj 4026 dC Loves Number Theory

    把我写吐了 太弱了
    首先按照欧拉函数性质 我只需要统计区间不同质数个数就好了
    一眼主席树
    其次我被卡了分解质因数这里
    可以通过质数筛时就建边解决
    不够灵性啊,不知道如何改

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1e6+1000;
    const int H = 5e4+5;
    const int M = H*100;
    const int mod = 1e6+777;
    
    int isprime[N];
    int prime[N]; int prnum[N]; int cc = 0;
    int rev[N], has[N];
    struct Node{
        int to,nex;
    }E[N*3];
    int head[N], eot = 0;
    int n,q;
    int a[H];
    int T[H], ls[M], rs[M], v[M]; int tot;
    int puf[H];
    
    void add(int x,int y) {
        E[eot].to = y; E[eot].nex = head[x]; head[x] = eot++;
    }
    int build(int l,int r) {
        int rt = tot++;
        v[rt] = 1;
        if(l == r) return rt;
        int mid = (l+r)>>1;
        ls[rt] = build(l,mid); rs[rt] = build(mid+1,r);
        return rt;
    }
    int upd(int pos,int num,int l,int r,int pr) {
        int rt = tot++;
        v[rt] = 1ll*v[pr]*num%mod;
        if(l == r) return rt;
        int mid = (l+r)>>1;
        if(pos <= mid) {
            ls[rt] = upd(pos,num,l,mid,ls[pr]); rs[rt] = rs[pr];
        }else {
            ls[rt] = ls[pr]; rs[rt] = upd(pos,num,mid+1,r,rs[pr]);
        }
        return rt;
    }
    int query(int L,int R,int l,int r,int rt) {
        if(L <= l && r <= R) return v[rt];
        int mid = (l+r)>>1;
        int ans = 1;
        if(L <= mid) ans = 1ll*ans*query(L,R,l,mid,ls[rt]) %mod;
        if(R > mid)  ans = 1ll*ans*query(L,R,mid+1,r,rs[rt]) %mod;
        return ans;
    }
    void debug(int l,int r,int rt) {
        printf("%d %d %d
    ",l,r,v[rt]);
        if(l == r) return;
        int mid  = (l+r)>>1;
        debug(l,mid,ls[rt]); debug(mid+1, r, rs[rt]);
    }
    
    
    int main(){
        memset(head,-1,sizeof(head));
        for(int i = 2; i < N; ++i) {
            if(!isprime[i]) {
                prime[++cc] = i;
                for(int j = i; j < N; j += i) {
                    isprime[j] = 1;
                    add(j,i); 
                }
            }
        }
        rev[0] = rev[1] = 1;
        for(int i=2;i< N;++i) {
            rev[i]= 1ll*(mod-mod/i)* rev[mod%i]%mod;
        }
        for(int i = 1; i <= cc; ++i) {
            prnum[prime[i]] = 1ll*(prime[i]-1) * rev[prime[i]] %mod;
        }
    
        while(~scanf("%d %d",&n,&q)) {
            memset(has,0,sizeof(has));
            for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
            tot = 0; puf[0] = 1;
            T[0] = build(1,n);  
            for(int i = 1; i <= n; ++i) {
                puf[i] = 1ll*puf[i-1]*a[i]%mod;
                int tmp = T[i-1];
                int tt = 1;
                for(int j = head[a[i]]; j != -1; j = E[j].nex) {
                    int x = E[j].to;
                    if(has[x]) 
                        tmp = upd(has[x],rev[prnum[x]],1,n,tmp);
                    tt = 1ll*tt*prnum[x]%mod; 
                    has[x] = i;
                }   
                T[i] = upd(i,tt,1,n,tmp);
            }
    
            int ans = 0;
            for(int i = 0; i < q; ++i) {
                int l,r; scanf("%d %d",&l,&r);
                l^=ans; r^=ans;
                ans = query(l,r,1,n,T[r]);
                ans = 1ll*ans*puf[r]%mod *rev[puf[l-1]] %mod;
                printf("%d
    ",ans);
            }
    
        }
        return 0;   
    }
    
  • 相关阅读:
    HDU 1025:Constructing Roads In JGShining's Kingdom(LIS+二分优化)
    HDU 3938:Portal(并查集+离线处理)
    HDU 1811:Rank of Tetris(并查集+拓扑排序)
    HDU 1074:Doing Homework(状压DP)
    HDU 1024:Max Sum Plus Plus(DP)
    最最最亲爱哒
    hlg-1332 买电脑 ---二分
    时间过得很快
    0514
    hlg1551Assemble--暴力求解
  • 原文地址:https://www.cnblogs.com/Basasuya/p/8433734.html
Copyright © 2011-2022 走看看