轻量级的巧妙解法
EOJ 1076 染氣球
一共有 N 只氣球,小強(qiáng)將 N 只氣球從左到右依次編號(hào)為 1、2、3……N,每次給 2 個(gè)整數(shù) a,b (a<=b),小強(qiáng)便騎上他的“小飛鴿 ” 牌電動(dòng)車從氣球 a 開(kāi)始到氣球 b 依次給每個(gè)氣球涂一次顏色。但是 N 次以后小強(qiáng)已經(jīng)忘記了第 I 個(gè)氣球已經(jīng)涂過(guò)幾次顏色了,你能幫他算出每個(gè)氣球被涂過(guò)幾次顏色嗎?
N <= 100000
dalao解法線段樹(shù),這里用了一種類似dp的解法,實(shí)際上是運(yùn)用了差分?jǐn)?shù)組前綴和。把從a刷到b的操作等價(jià)為++dp[a],–dp[b+1],最后求前綴和就可以得到答案。
可能需要多理解一會(huì)兒……不過(guò)并不難。
EOJ 3469/COCI 2016-2017 Contest#6 Savrsen
A number is perfect if it is equal to the sum of its divisors, the ones that are smaller than it. For example, number 28 is perfect because 28=1+2+4+7+14.
Motivated by this definition, we introduce the metric of imperfection of number N, denoted with f(N), as the absolute difference between N and the sum of its divisors less than N. It follows that perfect numbers’ imperfection score is 0, and the rest of natural numbers have a higher imperfection score. For example:
f(6)=|6?1?2?3|=0,
f(11)=|11?1|=10,
f(24)=|24?1?2?3?4?6?8?12|=|?12|=12.
Write a programme that, for positive integers A and B, calculates the sum of imperfections of all numbers between A and B: f(A)+f(A+1)+…+f(B).
難點(diǎn)在于求因子。普通方法一個(gè)個(gè)找因子時(shí)間復(fù)雜度太高,因此正難則反,采用類似埃氏篩法的方法:對(duì)于從1~B的數(shù),我們看它可能是誰(shuí)的因子并且存入表c中,最后計(jì)算結(jié)果。
這個(gè)方法的時(shí)間復(fù)雜度看起來(lái)也不低,不過(guò)實(shí)際上,通過(guò)計(jì)算不難發(fā)現(xiàn):對(duì)每個(gè)因子d我們循環(huán)了B/d次,所以總復(fù)雜度約為B/1+B/2+B/3+…+B/B,也就是B*(1+1/2+1/3+…+1/B),而這個(gè)式子約等于BlnB。也就是說(shuō),時(shí)間復(fù)雜度是O(BlogB)。
EOJ 49 素?cái)?shù)和排序
設(shè) f(x,y) 表示 [x,y] 區(qū)間中所有素?cái)?shù)的和。
給你 n 組 x,y,把它們按 f(x,y) 從小到大排序,若 f(x,y) 相等,則按 x 從小到大排序,若 f(x,y) 和 x 都相等,則按 y 從大到小排序。
1 ≤ n ≤ 10^5, max{yi} ? min{xi} ≤ 10^6,1 ≤ xi ≤ yi ≤ 10^12 (1≤i≤n).
不能開(kāi)10^12的數(shù)組,但注意到max{yi} ? min{xi} ≤ 10^6這一條件,考慮平移到[min{xi}, max{yi}]區(qū)間內(nèi),然后再用埃氏篩或歐拉篩,這樣就能得到范圍內(nèi)的質(zhì)數(shù)。最后預(yù)處理前綴和求解。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+5; const int maxm = 1e6+5;typedef long long ll; typedef struct fff{ll l, r, sum;} F;F f[maxn]; ll ans[maxm];int cmp(F a, F b) {if (a.sum != b.sum) return a.sum < b.sum;else if (a.l != b.l) return a.l < b.l;return a.r > b.r; }int main() {int n;cin >> n;ll l = 1e12, r = 0;for(int i = 0; i < n; ++i) {scanf("%lld%lld", &f[i].l, &f[i].r);l = min(f[i].l, l);r = max(f[i].r, r);}ll trans = l-1;for(ll i = l; i <= r; ++i)ans[i-trans] = i;if(l == 1) ans[1] = 0;for(int i = 2; i < maxm; ++i) {ll p = l - l%i;if(p < l) p += i;if(p == i) p += i;while(p <= r) {ans[p-trans] = 0;p += i;}}for(ll i = 1; i <= r-l+1; ++i) ans[i] += ans[i-1];for(int i = 0; i < n; ++i)f[i].sum = ans[f[i].r-trans] - ans[f[i].l-trans-1];sort(f, f + n, cmp);for(int i = 0; i < n; ++i)printf("f(%lld,%lld)=%lld\n", f[i].l, f[i].r, f[i].sum);return 0; }EOJ 2918 Kth-Number
Given an array a[1…n] of different integer numbers, what would be the k-th number in a[i…j] segment, if this segment was sorted?
1 <= n <= 10^5
似乎又是線段樹(shù)/劃分樹(shù)的題,不過(guò)還是可以暴力+優(yōu)化過(guò)。記錄好原數(shù)組中數(shù)的位置,然后排好序。根據(jù)k在范圍中的相對(duì)位置選擇從后往前/從前往后找。
評(píng)測(cè)結(jié)果:線段樹(shù)做法不到0.1s,本做法不到0.55s,應(yīng)該還算可以接受……
EOJ 3462(EOJ Monthly 2018.1) 最小OR路徑
給定一個(gè)有 n 個(gè)點(diǎn)和 m 條邊的無(wú)向圖,其中每一條邊 ei 都有一個(gè)權(quán)值記為 wi。
對(duì)于給出的兩個(gè)點(diǎn) a 和 b,求一條 a 到 b 的路徑,使得路徑上的邊權(quán)的 OR(位或)和最小,輸出這個(gè)值。(也就是說(shuō),如果將路徑看做邊的集合 {e1,e2,…,ek},那么這條路徑的代價(jià)為 w1 OR w2 OR … OR wk,現(xiàn)在求一條路徑使得其代價(jià)最小,輸出這個(gè)代價(jià)。) 如果不存在這樣的路徑,輸出 ?1。
2 ≤ n ≤ 10^4, 0 ≤ m ≤ 10^6, 0 ≤ ci ≤ 2^62?1
1 ≤ ui,vi,a,b ≤ n, a≠b
可能有重邊和自環(huán)。
假設(shè)答案二進(jìn)制位全為1,然后從高到低,如果不影響連通性就置0,最后得到的就是最優(yōu)方案。(看起來(lái)很暴力啊)
判斷連通性可以dfs,不過(guò)我覺(jué)得并查集好寫一點(diǎn)……
總結(jié)
- 上一篇: centos查看内存插槽及已插内存分布及
- 下一篇: 关于工业级GPU C-model所使用的