HH的军训(容斥)
1248: HH的军训
时间限制: 1 Sec 内存限制: 128 MB 提交: 95 解决: 11 [提交][状态][讨论版]题目描述
大学里,最难忘的事情莫过于军训了,白白的HH童鞋就被无情的晒黑了,话说军训期间,最怕的就是被教官逗了,俗话说:珍爱生命,远离教官。教官总爱让同学们站方阵,由于同学很多,难免会有前面的同学挡着后面的同学,为了远离教官,大家都希望自己站的位置教官看不到自己,现在假如同学们站在一个有坐标点的矩阵上,同学们都站在每一组整数点上,而教官站在坐标(0,0)上,请问此时有多少个位置教官可以直接看到!
输入
第一行输入一个T,代表T组测试数据。
接下来每行输入两个数字M,N,对于任意一个同学的坐标位置(x,y),都有1<=x<=M<=10000,1<=y<=N<=10000.
输出
输出有多少位置教官能够看到。
样例输入
2 1 4 2 3
样例输出
4 5
题解:容斥,少了个等号,错了半天。。。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> using namespace std; #define mem(x,y) memset(x,y,sizeof(x)) typedef long long LL; vector< int >p; void getp( int x){ for ( int i=2;i*i<=x;i++){ //太马虎了,错了半天,发现少了个等号。。。。。 if (x%i==0){ p.push_back(i); while (x%i==0)x/=i; } } if (x>1)p.push_back(x); } int getn( int x){ int sum=0; /*for(int i=0;i<p.size();i++){ cur=p[i]; sum+=x/cur; for(int j=i+1;j<p.size();j++){ cur*=-p[j]; sum+=x/cur; } }*/ //这种方法不行如果是2,3,4,则2,4选不了。。。。 for ( int i=1;i<(1<<p.size());++i){ int num=0,mult=1; for ( int k=0;k<( int )p.size();k++){ if (i&(1<<k)){ //1,10,11..1.10.100 mult*=p[k]; num++; } } int cur=x/mult; if (num&1)sum+=cur; //少了等号。。 else sum-=cur; } //printf("%d\n",sum); return sum; } int main(){ int T,M,N; scanf( "%d" ,&T); while (T--){ scanf( "%d%d" ,&M,&N); int ans=M; for ( int i=2;i<=N;i++){ p.clear(); getp(i); ans+=M-getn(M); } printf( "%d\n" ,ans); } return 0; } |
4 6被2 3挡了
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步