2019.11.8模擬賽

T1 div

給定\(m\)個不一樣的正整數\(a_1\)\(a_2\)\(\cdots\)請對\(1\)\(n\)每個\(k\)計算,在區間\([1,n]\)裏有多少正整數是\([a_1,a_m]\)中剛好\(k\)個數的約數。spa

暴力拆解就能夠了。code

int main()
{
    poread(n);
    poread(m);
    for(register int i = 1, x; i <= m; ++i)
    {
        poread(x);
        for(register int j = 1, lim = min(n, (int)sqrt(x)); j <= lim; ++j)
        {
            if(x % j == 0)
            {
                v[++tot] = j;
                if(j * j != x && x / j <= n)
                    v[++tot] = x / j;
            }
        }
    }
    sort(v + 1, v + 1 + tot);
    register int sum = 0;
    for(register int i = 1, cnt = 1; i <= tot && v[i] <= n; ++i)
    {
        v[i] == v[i - 1] ? ++cnt : (++ans[cnt], cnt = 1, ++sum);
    }
    ans[0] = n - sum;
    for(register int i = 0; i <= m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}

T2 market

在比特鎮一共有\(n\)家商店,編號依次爲\(1\)\(n\)。每家商店只會賣一種物品,其中第\(i\)家商店的物品單價爲\(c_i\),價值爲\(v_i\),且該商店開張的時間爲\(t_i\)
Byteasar 計劃進行\(m\)次購物,其中第\(i\)次購物的時間爲\(T_i\),預算爲\(M_i\)。每次購物的時候,Byteasar 會在每家商店購買最多一件物品,固然他也能夠選擇什麼都不買。若是購物的時間早於商店開張的時間,那麼顯然他沒法在這家商店進行購物。
如今 Byteasar 想知道,對於每一個計劃,他最多能購入總價值多少的物品。請寫一個程序,幫助 Byteasar 合理安排購物計劃。
注意:每次所花金額不得超過預算,預算也不必定要花完,同時預算不能留給其它計劃使用。排序

按照時間排序,保證可以取得已經開業的商店。
反向揹包,記錄取得i的價值的物品的最小代價,對於每一個詢問二分答案。class

signed main()
{
	poread(n), poread(m);
	for(register int i = 1; i <= n; ++i)
		poread(mk[i].c), poread(mk[i].v), poread(mk[i].t), mx += mk[i].v;
	for(register int i = 1; i <= m; ++i)
		poread(sp[i].t), poread(sp[i].m), sp[i].id = i;
	sort(mk + 1, mk + 1 + n);
	sort(sp + 1, sp + 1 + m);
	memset(f, 0x3f, sizeof(f));
	f[0] = 0;
	for(register int i = 1, k = 0; i <= m; ++i)
	{
		while(mk[k + 1].t <= sp[i].t && k < n)
		{
			++k;
			for(register int j = mx; j >= mk[k].v; --j)
				f[j] = min(f[j], f[j - mk[k].v] + mk[k].c);
			for(register int j = mk[k].v ; j >= 1; --j)
				f[j] = min(f[j + 1], f[j]); 
		}
		register int l = 0, r = mx, mid, res;
		while(l <= r)
		{
			mid = (l + r) >> 1;
			if(f[mid] > sp[i].m)
				res = mid, r = mid - 1;
			else 
				l = mid + 1;
		}
		ans[sp[i].id] = res - 1;
	}
	for(register int i = 1; i <= m; ++i)
		printf("%d\n", ans[i]);
	return 0;
}
相關文章
相關標籤/搜索