題目:http://community.topcoder.com/stat?c=problem_statement&pm=13060&rd=15996
參考:http://apps.topcoder.com/wiki/display/tc/TCO+2014+Round+2B
將數按對W的餘數進行分類。做題思維要非常清晰,難度不小,看題解看了半天才看懂。
代碼:
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <bitset>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
#define CHECKTIME() printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC)
typedef pair<int, int> pii;
typedef long long llong;
typedef pair<llong, llong> pll;
#define mkp make_pair
/*************** Program Begin **********************/
vector<vector<int>> g;
class AlwaysDefined {
public:
inline long long items(long long rem, long long upper, int W)
{
// rem + (cnt - 1) * W < upper
long long numbers = upper - rem;
return (numbers + W - 1) / W;
}
long long solve(int W, int rem, long long cnt)
{
if (cnt <= 0) {
return 0;
}
if (1 == rem) {
return cnt;
}
long long ans = 0;
for (int i = 0; i < g[rem].size(); i++) {
int x = g[rem][i];
long long smallest = rem + x * W;
long long newrem = smallest / rem;
ans += solve(W, newrem, items(x, cnt, rem)); // rem 爲一個週期
}
return ans;
}
long long countIntegers(long long L, long long R, int W) {
long long res = 0;
g.resize(W);
for (int i = 0; i < g.size(); i++) {
g[i].clear();
}
for (int rem = 1; rem < W; rem++) {
for (int x = 0; x < rem; x++) {
if ( (x * W) % rem == 0 ) {
g[rem].push_back(x);
}
}
}
for (int rem = 1; rem < W; rem++) {
res += solve(W, rem, items(rem, R + 1, W));
res -= solve(W, rem, items(rem, L, W));
}
return res;
}
};
/************** Program End ************************/