이모저모

14573 본문

BOJ

14573

Alpa 2017. 5. 20. 21:03


수열의 관계식은


A(n) = A(n-1) * (2^(n-2) + 2) (단 n >= 3)


그러므로


최대 공약수는 A(1)*A(min(i,j))

최소 공배수는 A(1)*A(max(i,j))

공배수는 2의 거듭제곱을 구해야 하므로

A(1)의 거듭제곱 + max(i,j) - 1 (단 i,j>=3)

합은 부분합을 이용 A(1)*(sum(j)-sum(i))

k번째 A(1)*A(k)



아래는 소스코드이다.


#include <iostream> 

#include <iterator>

#include <algorithm> 

#include <vector>

#include <list>

#include <map>

#include <set>

#include <queue>

#include <stack>

#include <string>

#include <cmath>

#include <cstdio>

#include <cstring>

using namespace std;

#define MOD 1000000007

#define INF 2147483647

#define LNF 9223372036854775807

#define pb push_back

#define mp make_pair

typedef long long ll;

typedef unsigned long long ull;


int q;

long long pre[1000001], sum[1000001];

int main () {

freopen("sample.txt", "r", stdin);

scanf("%d",&q);

long long c = 2;

sum[1]=pre[1]=pre[2]=1; sum[2]=2;

for(int i=3;i<1000001;i++){

pre[i] = (pre[i-1] * (c+2)) % MOD;

sum[i] = (sum[i-1] + pre[i]) % MOD;

c = (c*2) % MOD;

}


for(int k=0,type,a,i,j;k<q;k++){

scanf("%d",&type);

if(type == 1){

scanf("%d%d%d",&a,&i,&j);

int small = min(i,j);

printf("%lld\n",(a*pre[small])%MOD);

}

else if(type == 2){

scanf("%d%d%d",&a,&i,&j);

int ret = 0, big = max(i,j);

for(int x=2,y=1;x<=a;x*=2,y++) if(a%x == 0) ret = y;

if(big > 2) ret += big - 1;

printf("%d\n",ret);

}

else if(type == 3){

scanf("%d%d%d",&a,&i,&j);

printf("%lld\n",((MOD+sum[j]-sum[i-1])*a)%MOD);

}

else{

scanf("%d%d",&a,&i);

printf("%lld\n",(a*pre[i])%MOD);

}

return 0;

}



'BOJ' 카테고리의 다른 글

14552  (0) 2017.05.26
14583  (0) 2017.05.22
14579  (0) 2017.05.17
14568  (0) 2017.05.16
14567  (0) 2017.05.13
Comments