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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P1447 [NOI2010] 能量采集

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P1447 [NOI2010] 能量采集 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

P1447 [NOI2010] 能量采集

題意:

如果一棵植物與能量匯集機器(坐標為0,0)連接而成的線段上有 k 棵植物,則能量的損失為 2k + 1
給你一個n*m的植物園,問能量損失是多少
1<=n,m<=1e5

題解:

本題所求式子為:∑i=1n∑j=1ngcd(i,j)?2?1\sum_{i=1}^{n}\sum_{j=1}^{n}gcd(i,j)*2-1i=1n?j=1n?gcd(i,j)?2?1
式子如何求的?
參考這個AcWing 201. 可見的點
對于90%的數據,直接for循環就行
但是現在是acm賽制,要都過
本題思路參考這個,我只能說太秒了
設f[x]為gcd(i,j)=x的數對(i,j)的個數
答案就是∑x=1nf[x]?2?1\sum_{x=1}^{n}f[x]*2-1x=1n?f[x]?2?1
但是f[x]不好求啊
我們可以利用容斥來做
令g[x]為存在公因子=x的數對(i,j)的個數,注意不是最大公因數,而是存在公因子
g[x]=?nx???mx?g[x]=\lfloor \frac{n}{x}\rfloor*\lfloor \frac{m}{x}\rfloorg[x]=?xn????xm??
(1~n中是被x整除的數量為?nx?\lfloor \frac{n}{x} \rfloor?xn??
但是這些數中有一些最大公因數為2d,3d,4d,這些數重復添加,所以我們需要刪去
所以:f[x]=g[x]-∑i?x=2?xmin(n,m)f[i?x]\sum_{i*x=2*x}^{min(n,m)}f[i*x]i?x=2?xmin(n,m)?f[i?x]
從后向前枚舉x,這樣可以用已知的f[i*x]去更新f[x]
復雜度O(nlog n)

代碼:

#include <bits/stdc++.h> #include <unordered_map> #define debug(a, b) printf("%s = %d\n", a, b); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll= 1e18; const int INF_int= 0x3f3f3f3f; void read(){}; template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar) {x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...); } template <typename T> inline void write(T x) {if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0'); } void rd_test() { #ifdef ONLINE_JUDGE #elsestartTime = clock ();freopen("in.txt", "r", stdin); #endif } void Time_test() { #ifdef ONLINE_JUDGE #elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); #endif } const int N=100010; int n,m; ll f[N],ans; ll g[N]; int main(){scanf("%d%d",&n,&m);if(n>m)swap(n,m);for(int i=n;i>=1;--i){g[i]=1ll*(n/i)*(m/i);for(int j=i*2;j<=n;j+=i)g[i]-=f[j];f[i]=g[i];ans+=(i*2-1)*f[i];}printf("%lld",ans);return 0; }

總結

以上是生活随笔為你收集整理的P1447 [NOI2010] 能量采集的全部內容,希望文章能夠幫你解決所遇到的問題。

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