Poj 2800 Joseph's Problem - 找规律
2013-08-24 10:55
429 查看
题目大意:给定n和k,求 ∑1<=i<=n(k
mod i)
题目分析:n和k很大,直接算会TLE,但是可以先打表找规律。(点击可见数学推导)
随便找几组数据可以发现下面的规律
1)如果k/i的值相等,那么kmodi的值成等差数列(连续的)
2)如果k比n大,那么k/i的值随i的值增大而减小
3)如果k比n小,那么kmodi 大于k,当i大于k时
可见,主要解决的问题就是1),找到连续的成等差数列的区间。因为有规律3),所以不妨从后面往前找。如果发现了前面的规律,那么就会发现下 面的规律:
4) 从后往前找,如果从j开始出现等差数列(j为等差数列第一项),那么该等差数列的最后一项为k/(k/j+1)+1
但是等差数列不一定出现,如果k/(k/j+1) >= j。
代码:
mod i)
题目分析:n和k很大,直接算会TLE,但是可以先打表找规律。(点击可见数学推导)
随便找几组数据可以发现下面的规律
1)如果k/i的值相等,那么kmodi的值成等差数列(连续的)
2)如果k比n大,那么k/i的值随i的值增大而减小
3)如果k比n小,那么kmodi 大于k,当i大于k时
可见,主要解决的问题就是1),找到连续的成等差数列的区间。因为有规律3),所以不妨从后面往前找。如果发现了前面的规律,那么就会发现下 面的规律:
4) 从后往前找,如果从j开始出现等差数列(j为等差数列第一项),那么该等差数列的最后一项为k/(k/j+1)+1
但是等差数列不一定出现,如果k/(k/j+1) >= j。
代码:
#include <stdio.h> long long solve(int n,int k) { long long ans = 0; if(n > k) { ans += (long long)(n-k) * k; n = k; } int div = k/n; while(n > 1) { int id = k/(div+1); if(id >= n) { ans += k % n; n--; div = k/n; continue; } int s = k%n; int e = k%(id+1); ans += (((long long )(s+e)*(n-id))>>1); n = id; div++; } return ans; } int main() { int n,k; while(scanf("%d%d",&n,&k) != EOF) printf("%lld\n",solve(n,k)); return 0; }
相关文章推荐
- POJ 2800 Joseph’s Problem 数论找规律
- poj 2800 Joseph’s Problem(数论)
- (one day one problem)poj 2800 Joseph's Problem (数学)
- POJ 2800 Joseph's Problem(数论)
- POJ 2800 Joseph's Problem 笔记
- POJ 2800 Joseph's Problem
- POJ 2800 : Joseph\'s Problem (须仔细分析)
- UVa 1363 POJ 2800 Joseph's Problem
- Joseph's Problem 数论 找规律
- poj 2800 找规律
- UVA - 1363 Joseph's Problem(打表找规律)
- 【POJ】1663 - Number Steps(找规律)
- Uva16009 POJ 1906 Three Powers 数论 玄学找规律题 高精
- UVA 1363 - Joseph's Problem(数论)
- poj2506-Tiling(规律,大数)
- poj 1852 Ants <规律题>
- POJ-1012-Joseph-暴力/模拟
- POJ1012 Joseph解题报告
- POJ 2484-A Funny Game硬币排成环(博弈-找规律)
- POJ - 1835(找规律)