LOJ #3096. 「SNOI2019」数论 脑洞+循环节

碰到这种题第一反应就是找循环节.            

我们发现我们就是要求 $a[i]+P \times k=b[i] ( \mod Q)$ 中 $P$ 的 k 的个数.  

那么对于 $a[i]$ 来说,最大步数为 $\frac{T-1-a[i]}{P}$.    

而我们发现 $a[i]+ P \times k$ 的循环节是 $P \times k=0( \mod Q)$,这个循环节是 $lcm(P,Q)$,而 $k$ 的个数就是 $\frac{lcm(P,Q)}{P}$ 

枚举 $0$ ~ $Q$,然后对于 $i$ 向 $(i+P)%Q$ 连边,一定会形成若干个环长为 $\frac{Q}{gcd(P,Q)}$ 的环. 

那么,让每一个 $a[i]$ 在环上走 $\frac{T-1-a[i]}{P}$ 步,算一下点权和即可. 

upd:其实循环节大小都可以不算,直接暴力建图就行了.   

code:  

#include <bits/stdc++.h>         
#define ll long long 
#define N 1000006 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;   
ll T,ans,p[N];     
vector<int>s[N],v[N];    
int len,P,Q,n,m,a[N],b[N],tx[N],w[N],col[N],pos[N],num;        
int dfs(int x,int c) 
{
    if(col[x])   
        return 0;   
    col[x]=c;
    v[col[x]].push_back(x);  
    return tx[x]+dfs((x+P)%Q,c);    
}    
int find(int l,int x) 
{
    return s[col[x]][pos[x]+l]-s[col[x]][pos[x]];   
}
int main() 
{ 
    // setIO("input");    
    int i,j;          
    scanf("%d%d%d%d%lld",&P,&Q,&n,&m,&T);      
    for(i=1;i<=n;++i)   
        scanf("%d",&a[i]);    
    for(i=1;i<=m;++i)  
        scanf("%d",&b[i]);    
    if(P>Q) 
    {
        swap(P,Q); 
        swap(a,b); 
        swap(n,m);      
    } 
    len=Q/__gcd(P,Q);
    for(i=1;i<=m;++i)    
        tx[b[i]]=1;    
    for(i=1;i<=n;++i)   
        p[i]=(T-1-a[i])/P;   
    for(i=0;i<Q;++i) 
    {
        if(!col[i])    
            ++num,w[num]=dfs(i,num);   
    }     
    for(i=1;i<=num;++i) 
    {
        for(j=0;j<v[i].size();++j)   
            pos[v[i][j]]=j; 
        int t=v[i].size()-1;     
        for(j=0;j<t;++j)   
            v[i].push_back(v[i][j]);    
        s[i].push_back(tx[v[i][0]]);      
        for(j=1;j<v[i].size();++j)   
            s[i].push_back(s[i][j-1]+tx[v[i][j]]);          
    }  
    for(i=1;i<=n;++i) 
    {
        ans+=(ll)(p[i]/len)*w[col[a[i]]];       
        ans+=find(p[i]%len,a[i])+tx[a[i]];     
    }
    printf("%lld\n",ans);  
    return 0; 
}

  

 

posted @ 2020-03-14 09:18  EM-LGH  阅读(134)  评论(0编辑  收藏  举报