1. 程式人生 > >[2017浙工大之江學院決賽 L] qwb與整數對(離線,篩)

[2017浙工大之江學院決賽 L] qwb與整數對(離線,篩)

online con ons print include main amp i++ max

題目鏈接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=11

這題不會,看了檸檬巨的題解才知道可以篩出來。

枚舉a、b,然後求下m最小能是多少,可以滿足原式為整數。可以用(a*b)-(a*a+b*b)%(a*b)求。然後在m的基礎上算上a*b的倍數再更新到對應case上即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 6666;
 5 const int maxm = 44444;
 6 const
int Q = 20000; 7 int n[maxn], m[maxn], ret[maxn]; 8 vector<int> id[maxm]; 9 10 int main() { 11 // freopen("in", "r", stdin); 12 for(int i = 1; ~scanf("%d%d",&n[i],&m[i]) && (n[i]||m[i]); i++) { 13 id[m[i]+Q].push_back(i); 14 } 15 for(int a = 1; a <= 1000; a++) {
16 for(int b = a+1; b <= 1000; b++) { 17 int M = (a*b)-(a*a+b*b)%(a*b); 18 for(int t = 0; M+t*(a*b) <= Q; t++) { 19 for(int i = 0; i < id[M+t*(a*b)+Q].size(); i++) { 20 if(b < n[id[M+t*(a*b)+Q][i]]) ret[id[M+t*(a*b)+Q][i]]++; 21 }
22 } 23 for(int t = 1; M-t*(a*b) >= -Q; t++) { 24 for(int i = 0; i < id[M-t*(a*b)+Q].size(); i++) { 25 if(b < n[id[M-t*(a*b)+Q][i]]) ret[id[M-t*(a*b)+Q][i]]++; 26 } 27 } 28 } 29 } 30 for(int i = 1; n[i]||m[i]; i++) { 31 printf("Case %d: %d\n", i, ret[i]); 32 } 33 return 0; 34 }

[2017浙工大之江學院決賽 L] qwb與整數對(離線,篩)