HDU 2841 Visible Trees(容斥)题解
生活随笔
收集整理的這篇文章主要介紹了
HDU 2841 Visible Trees(容斥)题解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:有一塊(1,1)到(m,n)的地,從(0,0)看能看到幾塊(如果兩塊地到看的地方三點一線,后面的地都看不到)。
思路:一開始是想不到容斥...后來發現被遮住的地都有一個特點,若(a,b)有gcd(a,b)!= 1,那么就會被遮住。因為斜率k一樣,后面的點會被遮住,如果有gcd,那么除一下就會變成gcd = 1的那個點的斜率了。所以問題轉化為求gcd不為1有幾個點,固定一個點,然后容斥。
#include<set> #include<map> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; const int maxn = 1000 + 10; const int seed = 131; const int MOD = 1000000000 + 7; const int INF = 0x3f3f3f3f; int prime[maxn], p[maxn], pn; int a[maxn], an; void get(){memset(p, 0, sizeof(p));pn = 0;for(ll i = 2; i < maxn; i++){if(!p[i]){prime[pn++] = i;for(ll j = i * i; j < maxn; j += i)p[j] = 1;}} } int main(){int n, m;int T;get();scanf("%d", &T);while(T--){scanf("%d%d", &n, &m);ll ans = m;for(int i = 2; i <= n; i++){ll cnt = 0;//質因數分解an = 0;int x = i;for(int j = 0; prime[j] * prime[j] <= x && j < pn; j++){if(x % prime[j] == 0){a[an++] = prime[j];while(x % prime[j] == 0){x /= prime[j];}}}if(x > 1) a[an++] = x;//求gcd不為1for(int j = 1; j < (1 << an); j++){int num = 0;ll val = 1;for(int k = 0;k < an; k++){if(j & (1 << k)){num++;val *= a[k];}}if(num & 1) cnt += m / val;else cnt -= m / val;}ans += m - cnt;}printf("%lld\n", ans);}return 0; }?
轉載于:https://www.cnblogs.com/KirinSB/p/9568783.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的HDU 2841 Visible Trees(容斥)题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 埃及分数问题(带乐观估计函数的迭代加深搜
- 下一篇: exchange 删除邮件