BestCoder Round #80 1004 hdu 5668 中国剩余定理(m不互质版)

链接:戳这里

Circle

Time Limit: 2000/1000 MS (Java/Others)   Memory Limit: 65536/65536 K (Java/Others)

问题描述

\ \ \ \     Fye对约瑟夫游戏十分着迷.

\ \ \ \     她找到了n个同学,把他们围成一个圈,让他们做约瑟夫游戏,然后她得到了一个同学们出圈的编号序列.游戏是这样进行的:以同学1为起点,开始计数,计数到第k个同学,该同学出圈.出圈的同学将不参与之后的计数.

\ \ \ \     如今Fye找到了你,她想让你告诉他满足已知出圈序列的最小的k,如果你回答不上来,她就会很生气然后把你吊打一顿.

输入描述

\ \ \ \     第一行一个数T,为测试数据组数.

\ \ \ \     对每组测试数据,第一行一个数n.

\ \ \ \     第二行nn个数,为同学的出圈序列(第ai个出圈的人,编号为i).

\ \ \ \     输入数据必须是一个11到nn的合法排列.

\ \ \ \     1≤T≤10,2≤N≤20.

输出描述

\ \ \ \     对于每组测试数据,若存在合法的k,输出一个正整数,为合法的最小k,否则输出”Creation August is a SB!“.

输入样例

1

7

7 6 5 4 3 2 1

输出样例

420

思路:

约瑟夫环问题的一般步骤是数k步 然后当前的i出列

已知每一次出环的位置,那么模拟这个过程

(a[i-1]+k) %mi = ai % mi  其中ai为->在环内数ai还在环内的人  比如当前是123 上 2这个位置出环,那么我只需要2个没有标记的人,数完之后所在的位置  mi为环内还存活的人数

1:(0+k)%n=a1%n

2:(a1+k)%(n-1)=a2%(n-1)

....

3:(a[i-1]+k)%1=an%1

ai的话需要模拟求得,其实也就是数出cnt个人之后第bi个人出环  (出环的顺序已知

显然是中国剩余定理  前提是mi不互质

具体的中国剩余定理解析戳下面

http://yzmduncan.iteye.com/blog/1323599

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
    if(!b){
        d=a;
        x=1;
        y=0;
    } else {
        exgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
ll gcd(ll a,ll b){
    return b==0 ? a : gcd(b,a%b);
}
/* a*x = 1%m 逆元 */
ll inv(ll a,ll m){
    ll d,x,y;
    exgcd(a,m,d,x,y);
    if(d!=1) return -1;
    return (x%m+m)%m;
}
bool Merge(ll a1,ll m1,ll a2,ll m2,ll &a3,ll &m3){
    ll d=gcd(m1,m2);
    ll c=a2-a1;
    if(c%d!=0) return false;
    c=(c%m2+m2)%m2;
    c/=d;
    m1/=d;
    m2/=d;
    c*=inv(m1,m2);
    c%=m2;
    c*=m1*d;
    c+=a1;
    m3=m1*m2*d;
    a3=(c%m3+m3)%m3;
    return true;
}
ll china_Reminder(int n,ll *a,ll *m){
    ll a1=a[1],m1=m[1];
    ll a2,m2;
    for(int i=2;i<=n;i++){
        ll aa,mm;
        a2=a[i];
        m2=m[i];
        if(!Merge(a1,m1,a2,m2,aa,mm)) return -1;
        a1=aa;
        m1=mm;
    }
    ll t=(a1%m1+m1)%m1;
    if(t==0) return m1;
    return t;
}
ll a[22],b[22];
ll m[22];
int n;
int vis[22];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) m[i]=(ll)n-i+1LL;
        for(int i=1;i<=n;i++){
            int x;
            scanf("%d",&x);
            b[x]=(ll)i;
        }
        int w=0,cnt=0;
        mst(vis,0);
        for(int i=1;i<=n;i++){
            while(1){
                w=(w%n+n)%n+1;
                if(!vis[w]) cnt++;
                if(w==b[i]) break;
            }
            a[i]=(ll)cnt%m[i];
            vis[w]=1;
            cnt=0;
        }
        ll ans=china_Reminder(n,a,m);
        if(ans==-1) printf("Creation August is a SB!\n");
        else printf("%I64d\n",ans);
    }
    return 0;
}
时间: 2024-12-29 11:24:24

BestCoder Round #80 1004 hdu 5668 中国剩余定理(m不互质版)的相关文章

POJ 2891 中国剩余定理的非互质形式

中国剩余定理的非互质形式 任意n个表达式一对对处理,故只需处理两个表达式. x = a(mod m) x = b(mod n) km+a = b (mod n) km = (a-b)(mod n) 利用扩展欧几里得算法求出k k = k0(mod n/(n,m)) = k0 + h*n/(n,m) x = km+a = k0*m+a+h*n*m/(n,m) = k0*m+a (mod n*m/(n,m)) #include <cstdio> #include <cstring> #

hdoj-3579-Hello Kiki【中国剩余定理 &amp; 除数不互质】

Hello Kiki Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2590 Accepted Submission(s): 945 Problem Description One day I was shopping in the supermarket. There was a cashier counting coins seriou

hdoj-1573-X问题【中国剩余定理 &amp; 除数不互质】

X问题 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4255 Accepted Submission(s): 1359 Problem Description 求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], -, X mod a[i]

X问题(中国剩余定理+不互质版应用)hdu1573

X问题 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3921    Accepted Submission(s): 1253 Problem Description 求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod

HDU 5666 Segment——BestCoder Round #80

Segment Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Silen August does not like to talk with others.She like to find some interesting probl

BestCoder Round #3 1001 &amp;&amp; HDU 4907 Task schedule (预处理)

题目链接:HDU 4907 Task schedule 中文题. 思路:将工作表存在vis的组数中.预处理一遍.具体看代码 AC代码: #include<stdio.h> #include<string.h> bool vis[200100]; int tak[200100]; int main() { int j,i,ti; int n,m,t,num; while(scanf("%d",&t)!=EOF) { while(t--) { memset(

BestCoder Round #3 A hdu 4907 Task schedule

Task schedule                                                                        Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 307    Accepted Submission(s): 160 Problem Description 有一台机器

[HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP)

[HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP) 题面 有三个人从一张N个点无重边的有向无环图上的三个点出发,每单位时间,他们分别选择当前点的一条出边走下去.有向无环图点有点权,任意时刻他们所在的三个点两两点权相差不超过K.他们可以在任意三个点同时结束.求合法的路径总数.N≤50. 分析 暴力的做法,设\(dp[i][j][k]\)表示第一个人在i,第二个人在j,第三个人在k的方案数,然后枚举三个人接着到的地方x,y,z,倒推\(dp

Chinese remainder theorem again(中国剩余定理+不互质版+hud1788)

Chinese remainder theorem again Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1788 Appoint description:  System Crawler  (2015-04-27) Description 我知道部分同学最近在看中国剩余定理,就这个定理本身,还是比较简单的: 假设m1,m2,-,m