hdu 5392 Infoplane in Tina Town

本文深入探讨了算法、数据结构、人工智能等多个领域的关键概念和技术应用,从排序算法到深度学习,从数据挖掘到自动推理,全面展示了信息技术的最新发展与实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Infoplane in Tina Town

Time Limit: 14000/7000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 669    Accepted Submission(s): 121


Problem Description
There is a big stone with smooth surface in Tina Town. When people go towards it, the stone surface will be lighted and show its usage. This stone was a legacy and also the center of Tina Town’s calculation and control system. also, it can display events in Tina Town and contents that pedestrians are interested in, and it can be used as public computer. It makes people’s life more convenient (especially for who forget to take a device).

Tina and Town were playing a game on this stone. First, a permutation of numbers from  1  to  n  were displayed on the stone. Town exchanged some numbers randomly and Town recorded this process by macros. Town asked Tine,”Do you know how many times it need to turn these numbers into the original permutation by executing this macro? Tina didn’t know the answer so she asked you to find out the answer for her.

Since the answer may be very large, you only need to output the answer modulo  3230+1=3221225473  (a prime).
 

Input
The first line is an integer  T  representing the number of test cases.  T5

For each test case, the first line is an integer  n  representing the length of permutation.  n3106

The second line contains  n  integers representing a permutation  A1...An . It is guaranteed that numbers are different each other and all  Ai  satisfies (  1Ain ).
 

Output
For each test case, print a number  ans  representing the answer.
 

Sample Input
  
2 3 1 3 2 6 2 3 4 5 6 1
 

Sample Output
  
2 6
 

Source
 

先求出每个环的大小Ni,然后求所有Ni的最小公倍数。

那么就是对于每个质因数,求出现在Ni的最多的次数,然后做乘法即可。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
#define ll unsigned long long
#define maxn 3000007
int check[maxn];
vector<int> pri;
void init(){
    memset(check,0,sizeof(check));
    pri.clear();
    for(int i = 2;i < maxn; i++){
        if(check[i] == 0) {
            pri.push_back(i);
        }
        for(int j = 0;j < pri.size() ; j++){
            if(i*pri[j] >= maxn) break;
            check[i*pri[j]] = 1;
            if(i%pri[j] == 0) break;
        }
    }
}
int getn(){
    int a = 0;
    char x;
    do{
        x = getchar();
        if(x == ' ' || x == '\n') return a;
        a = a*10+x-'0';
    }while(1);
    return 1;
}

int num[maxn];
int ok[maxn];

vector<int> hehe;

ll mod = 3221225473ll;
int pnum[maxn];
ll cal(int u,int p){
    ll ans = 1;
    ll v = u;
    while(p){
        if(p & 1) ans = ans*v % mod;
        p/=2;
        v = v*v%mod;
    }
    return ans;
}


int main(){
    init();
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        getchar();
        for(int i = 1;i <= n; i++)
            num[i] = getn();
        for(int i = 1;i <= n; i++)
            ok[i] = pnum[i] = 0;
        hehe.clear();
        int mu = 1;
        for(int i = 1;i <= n; i++){
            if(ok[i] != 1){
                int u = i;
                int x = 0;
                while(ok[u] == 0){
                    x++;
                    ok[u] = 1;
                    u = num[u];
                }
                hehe.push_back(x);
            }
        }

        for(int i = 0;i < hehe.size(); i++){
            for(int j = 0;j < pri.size() && pri[j] <= hehe[i]; j++){
                if(hehe[i] % pri[j] == 0){
                    int x = 0;
                    while(hehe[i] % pri[j] == 0){
                        hehe[i] /= pri[j];
                        x++;
                    }
                    pnum[pri[j]] = max(pnum[pri[j]],x);
                    mu = max(mu,pri[j]);
                }
            }
        }

        ll ans = 1;
        for(int i = 1;i <= mu; i++){
            if(pnum[i] != 0)
            ans = ans*cal(i,pnum[i])%mod;
        }


        printf("%I64d\n",ans);

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GDRetop

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值