#include #include #include #include #define REP(i,a,b) for(i=a;ir=r; a->c=c; a->data = (int**)WorkMemory; WorkMemory = (void*)(a->data + r); rep(i,r){a->data[i] = (int*)WorkMemory; WorkMemory = (void*) (a->data[i] + c);} return WorkMemory; } void intMatrixSetZero(intMatrix *a){ int i,j; rep(i,a->r) rep(j,a->c) a->data[i][j]=0; } void intMatrixSetIdentity(intMatrix *a){ int i,mx; mx=a->r; if(mx>a->c) mx=a->c; intMatrixSetZero(a); rep(i,mx) a->data[i][i]=1; } void intMatrixMultipleMod(intMatrix *a,intMatrix *b,intMatrix *res,int m){ int i,j,k; intMatrixSetZero(res); rep(i,res->r) rep(k,b->r) if(a->data[i][k]) rep(j,res->c) { res->data[i][j]+=a->data[i][k]*b->data[k][j]; if(res->data[i][j]>=m) res->data[i][j]%=m; } } void intMatrixPowerMod(intMatrix *a,intMatrix *res,int k,int m,void *WorkMemory){ int i,j,n=a->r; intMatrix tmp1,tmp2; res->r=res->c=n; if(k==0){ intMatrixSetIdentity(res); return; } if(k==1){ rep(i,n)rep(j,n)res->data[i][j]=a->data[i][j]; return; } if(k==2){ intMatrixMultipleMod(a,a,res,m); return; } WorkMemory = newIntMatrix(&tmp1,n,n,WorkMemory); intMatrixPowerMod(a, &tmp1, k/2, m, WorkMemory); if(k%2==0) intMatrixMultipleMod(&tmp1,&tmp1,res,m); else { WorkMemory = newIntMatrix(&tmp2,n,n,WorkMemory); intMatrixMultipleMod(&tmp1,&tmp1,&tmp2,m); intMatrixMultipleMod(a,&tmp2,res,m); } } /* just sort */ void intSort(int d[],int s){int i=-1,j=s,k,t;if(s<=1)return;k=(d[0]+d[s-1])/2;for(;;){while(d[++i]k);if(i>=j)break;t=d[i];d[i]=d[j];d[j]=t;}intSort(d,i);intSort(d+j+1,s-j-1);} /* find the index of the first element which smaller than n */ int binarySearch(int d[],int size,int n){ int c = size/2; if(size==1){if(d[0]= 0){ /* if the hash contains hs */ priod = i; break; } uintHashSet(hs, i+1); } if(priod == -1){ // calculate priod ll add = 0; int SA = arr[0], SB = arr[1], NA, NB; for(;;){ k = uintHashGet(SA*P + SB) - 1; if(add > 0 && k >= 0){ priod = add - k; break; } add += per; NA = (SA * pw.data[0][0] + SB * pw.data[0][1] + pw.data[0][2]) % P; NB = (SA * pw.data[1][0] + SB * pw.data[1][1] + pw.data[1][2]) % P; SA = NA; SB = NB; } } /* printf("P = %d, Q = %d\n",P,Q); printf("A = %d, B = %d\n",A,B); printf("X = %d, Y = %d, Z = %d\n",X,Y,Z); printf("priod %d\n",priod);*/ first_appear_size = 0; rep(i,P){ // calculate the position of the fitst appearance of (C, i, 1) ll add = 0; int SA = C, SB = i, NA, NB; for(;;){ k = uintHashGet(SA*P + SB) - 1; if(k >= 0){ first_appear[first_appear_size] = (priod - add + k) % priod; first_appear_size++; break; } add += per; if(add > priod) break; NA = (SA * pw.data[0][0] + SB * pw.data[0][1] + pw.data[0][2]) % P; NB = (SA * pw.data[1][0] + SB * pw.data[1][1] + pw.data[1][2]) % P; SA = NA; SB = NB; } } intSort(first_appear, first_appear_size); while(Q--){ ll res = 0; ll s, t; scanf("%lld%lld",&L,&R); L--; if(L==0){ if(C==A) res++; R--; } else { L--; R--; } s = binarySearch(first_appear, first_appear_size, L % priod) + 1; t = binarySearch(first_appear, first_appear_size, R % priod); res += t-s+1; res += first_appear_size * (R/priod - L/priod); printf("%lld\n",res); } } return 0; }