日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU 5514 Frogs

發布時間:2023/12/8 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 5514 Frogs 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意

有一群青蛙,一開始都在0點,有一堆圈石子,編號從0~m-1的。
青蛙只能順時針跳,每個青蛙可以一次跳a[i]格,然后所有青蛙都這樣一直跳下去,這些青蛙踩過的石子的編號和是多少?

思考

讀了題,以為是暴力set過的,想到了之前set判重,Floyd判圈等等,結果遇到了MLE(第一次遇到),嚇得我懷疑了set。

// MLE 2016-10-23#include<cstdio> #include<cstring> #include<set> using namespace std;long long step[10010];int main() {int kas, cnt = 1;scanf("%d",&kas);while(kas--){ set<long long> id;long long n, m;memset(step, 0, sizeof(step));scanf("%ld%ld",&n, &m);for(int i = 0; i<n; i++)scanf("%ld",&step[i]);for(int i = 0; i<n; i++){ long long ini = step[i]%m;set<long long> temp;while(!temp.count(ini)){ temp.insert(ini);// printf(" %ld marked\n",ini);ini = (ini+step[i])%m;}set<long long>::iterator temp_it;for(temp_it = temp.begin(); temp_it!=temp.end(); temp_it++)id.insert(*temp_it);}//cal sum of step[];set<long long>::iterator it;long long sum = 0;for(it = id.begin(); it!=id.end(); it++)sum+=*it;printf("Case#%d: %ld\n",cnt++, sum);}return 0; }

然后果斷搜索題解,看到了容斥定理,才了解這道題的類型,然后找到優化方法:

對于第i只青蛙,他跳過的格子,一定是k*gcd(a[i],m)這種的
如果m小一點,我們就可以直接暴力了
當時m太大了,我們就分解m的因數之后,對于每個因數做暴力就好了
每個因數T的貢獻是 for(int i=1;i<=M/T;i++)ans += M*i;
第i只青蛙只能走到gcd(ai, m)的位置,我們就可以把m的因子提取出來,然后對青蛙能走到的因子位置打標記。(優化的關鍵) 青蛙能走到vis[i]因子位置就把vis[i]標記為1,然后num[i]表示m的第i個因子淚加的次數。如果vis[i]!=num[i]的話,就更新num。因子的個數大概是log2(m),所以時間復雜度大概為O(log2(m)2)。

當然也可以用set,但直接set不行。

#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef __int64 LL; const int maxn = 100010;int p[maxn], vis[maxn], num[maxn]; int gcd (int a, int b) {return b==0 ? a : gcd(b, a%b); }int main () {int T;scanf ("%d", &T);for (int t=1; t<=T; t++){int n, m, cnt = 0;scanf ("%d %d", &n, &m);for (int i=1; i<=sqrt(m); i++){if (m % i == 0){p[cnt ++] = i;if (i * i != m)p[cnt ++] = m / i;}}sort (p, p+cnt);int u;memset (vis, 0, sizeof(vis));memset (num, 0, sizeof(num));for (int i=0; i<n; i++){scanf ("%d", &u);int temp = gcd (u, m);for (int j=0; j<cnt; j++){if (p[j] % temp == 0)vis[j] = 1;}}vis[cnt-1] = 0;LL ans = 0;for (int i=0; i<cnt; i++){if (vis[i] != num[i]){LL temp = m / p[i];ans += temp * (temp - 1) / 2 * p[i] * (vis[i] - num[i]);temp = vis[i] - num[i];for (int j=i; j<cnt; j++)if (p[j] % p[i] == 0)num[j] += temp;}}printf ("Case #%d: %I64d\n", t, ans);}return 0; }

總結

以上是生活随笔為你收集整理的HDU 5514 Frogs的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。