728x90
문제
https://www.acmicpc.net/problem/14731
사용한 알고리즘
풀이
2일 전에 분할 정복을 이용한 거듭제곱으로 풀어서 맞왜틀하다가 던졌던 문제다.
어제 신촌캠프에서 비트마스킹을 배워서 그걸로 다시 풀어봤..다가 맞왜틀한 문제다.
결국 둘 다 AC를 받아냈는데
첫번째 풀이는
WA : ans += (((c*k)%m) *pow(k-1))%m;
AC : ans = (ans + ((c*k)%m) * pow(k-1))%m;
%m가 꼼꼼히 되지않은 것 때문이었고,
두번째 풀이는
WA : long long ans;
AC : long long ans =0;
지역변수로 선언해놓고 초기화 안해준 것 때문이었다 ;;
소스코드
첫번째 풀이(분할 정복을 이용한 거듭제곱)
#include <iostream>
using namespace std;
typedef long long ll;
ll m=1e9+7,ans;
ll pow(ll b){
if(b==0) return 1;
if(b%2==1) return (pow(b-1)*2) %m;
ll half=pow(b/2);
return (half*half)%m;
}
int main(){
ios_base::sync_with_stdio(false); cin.tie(NULL);
ll n,c,k; cin>>n;
while(n--){
cin>>c>>k;
ans = (ans + ((c*k)%m) * pow(k-1))%m; //★
}
cout<<ans;
return 0;
}
두번째 풀이(비트마스킹)
#include <iostream>
using namespace std;
typedef long long ll;
int main(){
ios_base::sync_with_stdio(false); cin.tie(NULL);
ll n, c, k, ans=0, mod=1e9+7; //★
cin>>n;
for(int i=0; i<n; i++){
cin>>c >>k;
// ans += c*k*(2^(k-1)) 를 하기위해 2^(k-1)를 구해보자
ll res=1, a=2, b=k-1; // a^b를 구해야 하는 상황 (결과값은 res에 담기)
/* b가 5일때 (예시)
5는 2진수로 101이고 우리가 구하는 것은
2^4*1 * 2^2*0 * 2^1*1 임.
*/
while(b){
if(b & 1) res = (res * a) % mod;
a = (a * a) % mod, b/=2;
}
ans = (ans + ((c * k)% mod) * res) % mod;
}
cout<<ans;
return 0;
}
728x90
'PS > Baekjoon' 카테고리의 다른 글
[백준/C++] 2961번: 도영이가 만든 맛있는 음식(S2) (6) | 2022.07.22 |
---|---|
[백준/C++] 17619번: 개구리 점프(G2) (0) | 2022.05.11 |
[백준/C++] 1202번: 보석 도둑(G2) (0) | 2022.03.21 |
[백준/C++] 11997번: Load Balancing (Silver)(G4) (0) | 2022.03.12 |
[백준/C++] 20924번: 트리의 기둥과 가지(G4) (0) | 2022.03.03 |
댓글