我叫张小黑
张小黑的挣扎生活
posts - 66,  comments - 109,  trackbacks - 0
 1#include<stdio.h>
 2#define Max_N 1000000000
 3#define M 100000000
 4int A[2][2]={1,1,1,0};
 5int kb[32];
 6int D_to_B(int k)
 7{
 8    int i=0;
 9        while(k>=1){
10            kb[i++]=k%2;
11            k/=2;}
12        return i;
13}
14void Multi(int a[2][2],int b[2][2])
15{
16    int i,j,k;
17    int temp[2][2]={0,0,0,0};
18    for(i=0;i<2;i++)
19        for(j=0;j<2;j++)
20            for(k=0;k<2;k++){
21                temp[i][j]+=int((__int64(a[i][k])*b[k][j])%M);
22                temp[i][j]%=M;}
23    for(i=0;i<2;i++)
24        for(j=0;j<2;j++)
25            a[i][j]=temp[i][j];
26}
27int Matrix_Multi(int a[2][2],int k)//a^k
28{
29    int t,i;
30    int temp[2][2]={1,0,0,1};
31    t=D_to_B(k);
32    for(i=t-1;i>=0;i--){
33        Multi(temp,temp);
34        if(kb[i]==1)Multi(temp,a);}
35    return (M+temp[0][0]-1)%M;
36}
37int main()
38{
39    int N,result;
40    while(scanf("%d",&N)!=EOF){
41        result=Matrix_Multi(A,N+1);
42        printf("%d\n",result);
43    }
44    return 0;
45}
posted @ 2008-03-06 22:19 zoyi 阅读(171) | 评论 (1)编辑 收藏
 1#include<iostream>
 2using namespace std;
 3#define M 98765431
 4#define Max_N 50000
 5int N,T,sum=0;
 6int cows[Max_N];
 7int t[32];
 8__int64 a,b;
 9int D_to_B(int x)
10{
11    int i=0;
12    while(x>=1){
13        t[i++]=x%2;
14        x/=2;}
15    return i;
16}
17void Multi(__int64 a[2][2],__int64 b[2][2])//矩阵a*b
18{
19    __int64 c[2][2];
20    int i,j,h;
21    memset(c,0,sizeof(c));
22    for(i=0;i<2;i++)
23        for(j=0;j<2;j++)
24            for(h=0;h<2;h++){
25                c[i][j]+=M+a[i][h]*b[h][j];//防止c[i][j]<0的情况
26                c[i][j]%=M;}
27    for(i=0;i<2;i++)
28        for(j=0;j<2;j++)
29            a[i][j]=c[i][j];
30}
31void Multi_k(__int64 a[2][2],int x)//a^x
32{
33    int k,i,j;
34    __int64 temp[2][2]={1,0,0,1};
35    k=D_to_B(x);//把x转为二进制
36    for(i=k-1;i>=0;i--){
37        Multi(temp,temp);
38        if(t[i]==1)Multi(temp,a);
39    }
40    for(i=0;i<2;i++)
41        for(j=0;j<2;j++)
42            a[i][j]=temp[i][j];
43}
44void compute_ab()
45{
46    __int64 A[2][2]={N-1,0,1,-1};
47    if(T==1){a=0;b=1;return;}
48    Multi_k(A,T-2);//求bT-1的一步,A^T-2
49    b=(A[1][0]*(N-1)+A[1][1])%M;//这是bT-1,用来求aT的,aT=(N-1)*bT-1
50    a=((N-1)*b)%M;
51    b=(A[1][0]*(N-1)*(N-1)+A[1][1]*(N-2))%M;//利用bT-1求bT
52}
53void solve()
54{
55    int i;
56    __int64 sum_i,result;
57    for(i=0;i<N;i++){
58        sum_i=(sum+M-cows[i])%M;//sum除了第i头牛
59        result=(b*sum_i+a*cows[i])%M;
60        printf("%I64d\n",result);}
61}
62int main()
63{
64    /*freopen("1.in","r",stdin);
65    freopen("3.ans","w",stdout);*/
66    int i;
67    scanf("%d%d",&N,&T);
68    compute_ab();
69    for(i=0;i<N;i++){
70        scanf("%d",&cows[i]);
71        cows[i]%=M;
72        sum+=cows[i];
73        sum%=M;}
74    solve();
75    return 0;
76}
77
posted @ 2008-03-05 17:03 zoyi 阅读(208) | 评论 (0)编辑 收藏

 

 1#include<iostream>
 2using namespace std;
 3#define Max_N 100
 4#define Max 60
 5typedef struct bigint{
 6    int data[Max];
 7    int len;
 8    friend bigint operator+(bigint,bigint);
 9    friend bigint operator*(bigint,bigint);
10    void operator=(const bigint&y){
11        this->len=y.len;
12        for(int i=0;i<y.len;i++)
13            this->data[i]=y.data[i];
14    }
15}BIGINT;
16BIGINT Trees[Max_N+1];
17BIGINT operator+(BIGINT x,BIGINT y)
18{
19    BIGINT r;
20    int rlen=x.len>y.len?x.len:y.len;
21    int tmp,i,jinwei=0;
22    for(i=0;i<rlen;i++){
23        tmp=x.data[i]+y.data[i]+jinwei;
24        r.data[i]=tmp%10;
25        jinwei=tmp/10;}
26    if(jinwei)r.data[rlen++]=jinwei;
27    r.len=rlen;
28    return r;
29}
30void print(BIGINT x)
31{
32    for(int i=x.len-1;i>=0;i--)
33        printf("%d",x.data[i]);
34    printf("\n");
35}
36BIGINT operator*(BIGINT x,BIGINT y)
37{
38    BIGINT r;
39    int i,j;
40    memset(r.data,0,sizeof(r.data));
41    r.len=x.len+y.len;
42    for(i=0;i<x.len;i++)
43        for(j=0;j<y.len;j++)
44            r.data[i+j]+=x.data[i]*y.data[j];
45    for(i=0;i<r.len;i++){
46        r.data[i+1]+=r.data[i]/10;
47        r.data[i]%=10;}
48    while(r.data[i]){
49        r.data[i+1]+=r.data[i];
50        r.data[i]%=10;
51        i++;}
52    while(i>=0&&!r.data[i])i--;
53    r.len=i+1;
54    return r;
55}
56void init()
57{
58    int i,j;
59    memset(Trees,0,sizeof(Trees));
60    Trees[0].data[0]=1;
61    Trees[0].len=1;
62    for(i=1;i<=Max_N;i++)
63        for(j=0;j<i;j++)
64            Trees[i]=Trees[i]+Trees[j]*Trees[i-j-1];
65}
66int main()
67{
68    int n;
69    init();
70    while(scanf("%d",&n)!=EOF)
71        print(Trees[n]);
72    return 0;
73}
posted @ 2008-03-02 17:10 zoyi 阅读(202) | 评论 (2)编辑 收藏
这道题是问题求解和程序设计的作业题,刚拿到这道题的时候,我完全没与递推的概念,第一反应完全是离散数学里面叫得容斥原理,典型的错排问题,一共有n对新人,有m对是错误的,首先通过c(n,m)选出错误的新人是哪些,然后就是算出这m对新人错误排列的方法。
根据容斥原理的公式推出m对错误的情况有m!-c(m,1)(m-1)!+c(m,2)(m-2)!+.....+(-1)^mc(m,m)0!;
在乘上c(n,m)就好了
化简后得a(n,m)(1-1/1!+1/2!-....+(-1)^m/m!);
算到这里我就犯愁了,这括号了的这些个东西怎么算阿,脑子完全堵住了,缓过神来才发现,要实现它并不困难
程序如下:
 1#include<stdio.h>
 2__int64 f(int n,int m){
 3    __int64 r,tmp1=1;
 4    int i;
 5    for(i=n;i>n-m;i--)
 6        tmp1*=i;
 7    r=tmp1;
 8    for(i=1;i<=m;i++){
 9        tmp1=(-tmp1)/i;
10        r+=tmp1;}
11    return r;
12}
13int main(){
14    int t,m,n;
15    __int64 result;
16    scanf("%d",&t);
17    while((t--)>0){
18        scanf("%d%d",&n,&m);
19        result=f(n,m);
20        printf("%I64d\n",result);
21    }
22    return 0;
23}
posted @ 2008-03-02 17:03 zoyi 阅读(224) | 评论 (1)编辑 收藏
http://acm.pku.edu.cn/JudgeOnline/problem?id=2480
 这道题改了两天,里面用到了整数因子分解,筛选素数,求欧拉函数,
以下是和partychen的聊天记录,既然他把那么难敲得证明都
敲出来了,那我就只接捻好了HOHO~~
主要公式sima(N/pi)*pi
另外这个公式是可积的
陈俊奎 10:13:35
m的约数为x1,x2,x3...xp
陈俊奎 10:13:48
n的约数为y1,y2,y3....yp
陈俊奎 10:14:05
那么有gcd(xi,yi)=1
陈俊奎 10:15:14
那么m*n的任意约数T,有唯一分解T=xi*yj
陈俊奎 10:16:47
T*E(m*n/T)=xi*yi*E(m/xi* n/ yj)=xi*E(m/xi)*yj*E(n / yj)
陈俊奎 10:18:09
f(m*n)=sima(xi*E(m/xi)*yj*E(n / yj))=(sima(xi*E(m/xi))*(sima(yj*E(n/ yj)))=f(m)*f(n)
陈俊奎 10:19:31
f(12)=f(2^2)*f(3)
陈俊奎 10:20:00
f(3)=1*E(3)+3*E(1)=2+3=5
陈俊奎 10:21:14
f(2^2)=1*E(2^2)+2*E(2)+4*E(1)=(2-1)*2^(2-1)+2*(2-1)+4*1
陈俊奎 10:21:25
=2+2+4=8
 1#include<iostream>
 2using namespace std;
 3#define Max_N 50000
 4#define Max_P 5200
 5#define __int64 _int64
 6int Prime[Max_N];//对素数的标记
 7int P_div[Max_P];//存储素数约数
 8int P_mi[Max_P];//存储素数约数的幂
 9void init()//筛选素数
10{
11    _int64 i,j;
12    for(i=2;i<Max_N;i++)
13        if(!Prime[i])
14            for(j=2;j*i<Max_N;j++)Prime[j*i]=1;
15}
16_int64 phi(int p,int e)//欧拉
17{
18    if(e==0||p==1)return 1;
19    if(e==1)return p-1;
20    _int64 i;
21    _int64 result=1;
22    for(i=1;i<e;i++)
23        result*=p;
24    result*=(p-1);
25    return result;
26}
27int get(int i,int e)
28{
29    int j;
30    int r=1;
31    for(j=e;j<P_mi[i];j++)
32        r*=P_div[i];
33    return r;
34}
35int factorization(int n)//整数因子分解
36{
37    int i,j=0;
38    for(i=2;i<Max_N&&n>1;i++)
39        if(!Prime[i]&&n%i==0){
40            P_div[j]=i;
41            while(n%i==0){
42                ++P_mi[j];
43                n/=i;}
44            j++;}
45        if(i>=Max_N||!j){//好重要的疏漏!!!大素数因子没有存入P_div中
46            P_div[j]=n;//吸取教训的地方!!
47            P_mi[j++]=1;}
48        return j;
49}
50int main()
51{
52    //freopen("1.in","r",stdin);
53    //freopen("1.ans","w",stdout);
54    int N;
55    int i,j,t,h,tmp1;
56    _int64 tmp2;
57    _int64 result,p;
58    memset(Prime,0,sizeof(Prime));
59    init();
60    while(scanf("%d",&N)!=EOF){//
61        result=1;
62        memset(P_div,0,sizeof(P_div));
63        memset(P_mi,0,sizeof(P_mi));
64        t=factorization(N);
65        for(i=0;i<t;i++){
66                for(p=0,j=0,h=1;j<=P_mi[i];j++){
67                    tmp1=get(i,j);
68                    tmp2=phi(P_div[i],j);
69                    p+=tmp2*tmp1;}
70                result*=p;}
71        printf("%I64d\n",result);
72    }    
73    return 0;
74}
posted @ 2008-03-01 20:19 zoyi 阅读(369) | 评论 (0)编辑 收藏
http://acm.pku.edu.cn/JudgeOnline/problem?id=3370
鸟巢原理
&&fflush害死人的错
 1#include<iostream>
 2using namespace std;
 3#define Max_N 100001
 4int c,n,i,j,tem;
 5char t;
 6int candy[Max_N];
 7int sum[Max_N];
 8int b[Max_N];
 9int main()
10{
11    
12    sum[0]=0;
13    while(1){
14        scanf("%d%d",&c,&n);
15        getchar();
16        if(!c&&!n)break;
17        if(!c){printf("no sweets\n");continue;}
18        memset(candy,0,sizeof(candy));
19        memset(b,0,sizeof(b));
20        for(i=1;i<=n;i++){
21            while(t=getchar()){//通过getchar的方法来读数
22                if(t==' '||t=='\n')break;
23                candy[i]=10*candy[i]+t-'0';}
24            if(!(candy[i]%c)){//如果读到的数能被c整除,就已经可以了
25                printf("%d\n",i);
26                break;}
27            sum[i]=(sum[i-1]+candy[i])%c;//如果当前读到的所有数之和也满足情况,这样也行
28            if(!sum[i]){
29                for(j=1;j<=i;j++){
30                    printf("%d",j);
31                    if(j!=i)putchar(' ');
32                    else putchar('\n');
33                }
34                break;}
35        }
36        for(j=i+1;j<=n;j++)scanf("%d",&tem);
37        if(i>n)//处理剩下的一众情况
38            for(i=1;i<=n;i++){
39                if(!b[sum[i]])
40                    b[sum[i]]=i;
41                else {
42                    for(j=b[sum[i]]+1;j<=i;j++){
43                        printf("%d",j);
44                        if(j!=i)putchar(' ');
45                        else putchar('\n');
46                    }
47                    break;}}
48
49    }        
50    return 0;
51}
posted @ 2008-02-27 22:02 zoyi 阅读(280) | 评论 (0)编辑 收藏
http://acm.pku.edu.cn/JudgeOnline/problem?id=3363
这道题刚开始看懂题时,我是死活不敢动手,就是不相信就是这么做,后来用百度搜了搜这题,在一个博客上看到他对这题的想法,简单的模拟,我这才开始写,值得一提的是,这道题帮助我发现了个我不好的习惯,今天因为这个习惯,使两道题都tl,我总是在没读完数据,输出结果后,就经过一个fflush来刷干净缓冲,但是把结束条件也刷掉了,使程序断不了,导致tl。(这都多些partychen :-))
 1#include<iostream>
 2using namespace std;
 3#define Max 100
 4int main()
 5{
 6    int n,m,r,c,cont;
 7    int i,j,p,q,t;
 8    int map[Max][Max];
 9    char row[Max];
10    while(scanf("%d%d%d%d",&n,&m,&r,&c)){
11        getchar();
12        memset(map,0,sizeof(map));
13        if(!n&&!m&&!r&&!c)break;
14        cont=0;
15        t=0;
16        for(i=0;i<n;i++){
17            gets(row);
18            for(j=0;j<m;j++){
19                if(map[i][j]!=row[j]-'0')
20                    if(i+r<=n&&j+c<=m){
21                        for(q=i;q<i+r;q++)
22                            for(p=j;p<j+c;p++){
23                                map[q][p]+=1;
24                                map[q][p]%=2;}
25                            cont++;}
26                    else {t=1;break;}
27            }
28            if(t==1)break;
29        }
30        if(t==1){
31            while((++i)<n)gets(row);
32            printf("-1\n");}
33        else printf("%d\n",cont);
34    }
35    return 0;
36}
posted @ 2008-02-27 21:58 zoyi 阅读(298) | 评论 (0)编辑 收藏

http://acm.pku.edu.cn/JudgeOnline/problem?id=2356
discuss里说用鸽巢原理,我感觉我写出来的应该是o(n),可是程序跑了500多

 1#include<stdio.h>
 2#include<algorithm>
 3using namespace std;
 4#define Max_N 10000
 5struct node{
 6    int num;
 7    int yu;
 8};
 9int N;
10int get[Max_N];
11struct node sum[Max_N]; 
12bool cmp(struct node a,struct node b)
13{
14    if(a.yu<b.yu)return true;
15    else if(a.yu==b.yu)return a.num<b.num;
16    else return false;
17}
18void solve()
19{
20    int i,j;
21    sum[0].yu=get[0]%N;
22    sum[0].num=0;
23    for(i=1;i<N;i++){
24        sum[i].yu=sum[i-1].yu+get[i];
25        sum[i].yu%=N;
26        sum[i].num=i;}//第一个数是get的第一个数,第二个数是前两个数的和取余,一共是N个数,就有N个和
27    //若其中一个和取余是0,显然成立,否则根据鸽巢原理,N个数占N-1个位子,显然会有一样的
28    sort(sum,sum+N,cmp);
29    if(!sum[0].yu){
30        printf("%d\n",sum[0].num+1);
31        for(i=0;i<=sum[0].num;i++)
32            printf("%d\n",get[i]);
33        return;
34    }
35    else {
36        for(i=0;i<N-1;i++)
37            if(sum[i].yu==sum[i+1].yu){
38                printf("%d\n",sum[i+1].num-sum[i].num);
39                for(j=sum[i].num+1;j<=sum[i+1].num;j++)
40                    printf("%d\n",get[j]);
41                return;}
42        
43    }
44    printf("0\n");
45}
46int main()
47{
48    int i;
49    while(scanf("%d",&N)!=EOF){
50        for(i=0;i<N;i++){
51            scanf("%d",&get[i]);
52        }
53    solve();}
54    return 0;
55}
以下是经过学习别人代码后重写的代码,0ms
 1#include<iostream>
 2using namespace std;
 3#define Max_N 10001
 4int main()
 5{
 6    int N,i,j;
 7    int get[Max_N];
 8    int sum[Max_N];
 9    int b[Max_N];
10    sum[0]=0;
11    memset(b,0,sizeof(b));
12    scanf("%d",&N);
13    for(i=1;i<=N;i++){
14        scanf("%d",&get[i]);
15        if(!(get[i]%N)){
16            printf("1\n%d\n",get[i]);break;}
17        else {
18            sum[i]=(sum[i-1]+get[i])%N;
19            if(!sum[i]){
20                printf("%d\n",i);
21                for(j=1;j<=i;j++)
22                    printf("%d\n",get[j]);
23                break;}
24        }
25    }
26    if(i>N){
27        for(i=1;i<=N;i++){
28            if(!b[sum[i]])
29                b[sum[i]]=i;
30            else{
31                printf("%d\n",i-b[sum[i]]);
32                for(j=b[sum[i]]+1;j<=i;j++)
33                    printf("%d\n",get[j]);
34                break;}
35        }
36    }
37    return 0;
38}
posted @ 2008-02-26 20:39 zoyi 阅读(224) | 评论 (0)编辑 收藏
http://acm.pku.edu.cn/JudgeOnline/problem?id=1597
这道题是冲着他是数论题去做的,开始对他给的这个式子
seed(x+1) = [ seed(x) + STEP ] % MOD很困惑,然后就开始翻算法导论,刚刚看完解模线性方程,看这个式子和这种方程长得有点相像,就在反复琢磨,钻牛角尖,突然眼睛一亮,想到了,模加法,这就是个以MOD的群,这道题就变成了,初始的A值是什么的情况下,使得子群的模为MOD
是在A和MOD互质的情况下,这道题就迎刃而解了
下面是代码:
 1#include<stdio.h>
 2int EUCLD(int a,int b)
 3{
 4    if(!b)return a;
 5    else return EUCLD(b,a%b);
 6}
 7int main()
 8{
 9    int STEP,MOD,d;
10    while(scanf("%d%d",&STEP,&MOD)!=EOF)
11    {
12        d=EUCLD(STEP,MOD);
13        printf("%10d%10d",STEP,MOD);
14        if(d==1)printf("    Good Choice\n\n");
15        else printf("    Bad Choice\n\n");
16    }
17    return 0;
18}
posted @ 2008-02-25 20:30 zoyi 阅读(287) | 评论 (0)编辑 收藏
http://acm.pku.edu.cn/JudgeOnline/problem?id=1008
 1#include<stdio.h>
 2#include<string.h>
 3int main()
 4{
 5    const char Haab_m[19][10]={"pop","no","zip","zotz","tzec","xul","yoxkin","mol","chen","yax",
 6                      "zac","ceh","mac","kankin","muan","pax","koyab","cumhu","uayet"};
 7    const char Tzolkin_d[20][10]={"imix","ik","akbal","kan","chicchan","cimi","manik","lamat","muluk","ok",
 8        "chuen","eb","ben","ix","mem","cib","caban","eznab","canac","ahau"};    
 9    int i,n,Day,Year,total_d;
10    int Y,Di,M,tem_d;
11    char Month[10];
12    scanf("%d",&n);
13    printf("%d\n",n);
14    while((n--)>0){
15        scanf("%d. %s %d",&Day,&Month,&Year);
16        total_d=365*Year;
17        for(i=0;i<19;i++)
18            if(strcmp(Month,Haab_m[i])==0){
19                total_d+=Day+1;
20                break;}
21            else total_d+=20;
22        if(i==19)total_d+=Day+1;
23        tem_d=total_d%260;
24        if(!tem_d){
25            Y=total_d/260-1;
26            M=13;
27            Di=19;}
28        else {
29            Y=total_d/260;
30            M=tem_d%13;
31            Di=(tem_d+19)%20;
32            if(!M)M=13;}
33        printf("%d %s %d\n",M,Tzolkin_d[Di],Y);
34    }
35    return 0;
36}
posted @ 2008-02-25 19:33 zoyi 阅读(487) | 评论 (0)编辑 收藏
仅列出标题
共7页: 1 2 3 4 5 6 7 
欢迎光临 我的白菜菜园

<2008年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(8)

随笔分类

随笔档案

文章档案

相册

acmer

online judge

队友

技术

朋友

搜索

  •  

最新评论

阅读排行榜

评论排行榜