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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

codeforces 7.22 F Pairwise Modulo

發布時間:2025/3/12 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 codeforces 7.22 F Pairwise Modulo 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

codeforces 7.22 F Pairwise Modulo

給出n個數的數列a,每個數互不相同且都小于3e5,求出qk=∑1<=i,j<=kaimodajq_k=\sum_{1<=i, j<=k}a_i~mod~a_jqk?=1<=i,j<=k?ai??mod?aj?
其中n <= 2e5

題意很簡單,就是求出前1到n個數兩兩之間相互取mod之后的和,但是拿到題的時候一點思路都沒有,靠著題解過活。

分析qkq_kqk?,可以將其分為兩個部分,一個是sks_ksk?,表示編號大的數mod編號小的數的和,另一個是tkt_ktk?,表示編號小的數mod編號大的數。這兩個部分可以分開分析然后求和。容易得到sk=sk?1+∑i=1k?1akmodais_k=s_{k-1}+\sum_{i=1}^{k-1}a_k~mod~a_isk?=sk?1?+i=1k?1?ak??mod?ai?,把mod拆成兩個部分akmodai=ak?ai?akai?a_k~mod~a_i=a_k-a_i\lfloor\frac{a_k}{a_i}\rfloorak??mod?ai?=ak??ai??ai?ak???,那么sk=sk?1+(k?1)ak?∑i=1k?1ai?akai?s_k=s_{k-1}+(k-1)a_k-\sum_{i=1}^{k-1}a_i\lfloor\frac{a_k}{a_i}\rfloorsk?=sk?1?+(k?1)ak??i=1k?1?ai??ai?ak???

關鍵就是最后面一個部分怎么求解。對于每個數aia_iai?,當它后面加入一個新的數aka_kak?時,這個部分對于答案的貢獻就是?ai?akai?-a_i\lfloor\frac{a_k}{a_i}\rfloor?ai??ai?ak???。所以,當我們在加入aia_iai?的時候,可以計算出對于其余可能出現的每一個數,對于答案的貢獻是多少。也就是,如果后面出現的數是0到ai?1a_i-1ai??1,那么貢獻為0;如果是aia_iai?2ai?12a_i-12ai??1,那么貢獻是?ai-a_i?ai?;如果是2ai2a_i2ai?3ai?13a_i-13ai??1,那么貢獻是?2ai-2a_i?2ai?,以此類推。這是一個區間修改,并且這個貢獻是可以疊加的,也就是說,它可以直接加在ai?1a_{i-1}ai?1?對于aka_kak?的貢獻上,當后面出現aka_kak?時,不用去糾結這個貢獻是ai?1a_{i-1}ai?1?還是aia_iai?所帶來的。這就可以想到用線段樹維護。

不過會發現,每一次加一個數進去會進行MAXNai\frac{MAXN}{a_i}ai?MAXN?次修改(MAXN==3e5),不過我們已經知道了aia_iai?兩兩互不相同。有一個結論:n/1+n/2+n/3+...+n/n=nlognn/1+n/2+n/3+...+n/n=n~lognn/1+n/2+n/3+...+n/n=n?logn
來自ccpc綿陽站的痛苦面具

tkt_ktk?的轉化與sks_ksk?大同小異,sks_ksk?是區間修改單點查詢而tkt_ktk?是區間修改單點查詢。

這樣復雜度是O(nlog2MAXN)O(nlog^2MAXN)O(nlog2MAXN),是可以過的。不過我T了,應該是線段樹常數太大,今天不想改了,有空學一下非遞歸線段樹。

并且由于我們需要的操作是區間修改單點查詢和區間修改單點查詢,那么可以用樹狀數組來維護,常數會優秀很多。

貼的是T的代碼,感受一下原理即可。


更新:樹狀數組又好寫又快,換成樹狀數組的ac代碼了

const int N = 2e5 + 10, MAXN = 3e5 + 10;long long bitree[MAXN][2]; int a[N];inline int lowbit(int x) {return x & -x; }void change(int x, int d, int num) {while (x < MAXN){bitree[x][num] += d;x += lowbit(x);} }long long search(int x, int num) {long long ans = 0;while (x){ans += bitree[x][num];x -= lowbit(x);}return ans; }int main() {//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);int T = 1;//T = read();while (T --){int n = read();long long ans = 0, sum = 0;for (int i = 1; i <= n; i ++){a[i] = read();ans += (long long)(i - 1) * a[i];ans += sum;ans -= search(a[i], 0);for (int j = a[i]; j < MAXN; j += a[i])ans -= (search(min(MAXN - 1, j + a[i] - 1), 1) - search(j - 1, 1)) * (j / a[i]) * a[i];sum += a[i];for (int j = a[i]; j < MAXN; j += a[i]){change(j, (j / a[i]) * a[i], 0);change(j + a[i], -(j / a[i]) * a[i], 0);}change(a[i], 1, 1);cout << ans;if (i < n) cout << " ";}}return 0; }

總結

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

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