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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Codeforces Round #470 (Div. 1)

發布時間:2024/3/24 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces Round #470 (Div. 1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Contests 鏈接:Codeforces Round #470 (Div. 1)
過題數:3
排名:315/1183

A. Primal Sport

題意

AliceAliceBobBob 兩人在玩一個游戲,AliceAlice 先開始,兩人輪流進行,第 ii 次游戲中,對于一個整數 XiXi,選擇一個素數 p<Xip<Xi,然后找到一個最小的整數 YY,使得 YXY≥XYY 能被 pp 整除,將這個數字作為下一次游戲的新值 Xi+1Xi+1 繼續進行游戲,現在游戲已經進行了兩次,得到了 X2X2 的值,問最小的可能的 X0?(X03)X0(X0≥3) 的值為多少。

輸入

輸入為一個整數 X2?(4X2106)X2(4≤X2≤106),數據保證 X2X2 是合數。

輸出

輸出最小的可能的 X0X0 的值。

樣例

輸入
14
輸出
6
提示
X0=6X0=6,則其中一種合法的游戲過程如下:
1. AliceAlice 選擇 p=5p=5X1X1 的值為 1010
2. BobBob 選擇 p=7p=7X2X2 的值為 1414
輸入
20
輸出
15
提示
X0=15X0=15,則其中一種合法的游戲過程如下:
1. AliceAlice 選擇 p=2p=2X1X1 的值為 1616
2. BobBob 選擇 p=5p=5X2X2 的值為 2020
輸入
8192
輸出
8191

題解

我們可以根據 XiXi 的值確定 Xi?1Xi?1 的合法的取值區間:[Xi?p+1,Xi][Xi?p+1,Xi],其中 ppXiXi 的最大的質因子,對于 Xi?1Xi?p+1Xi?1≥Xi?p+1 的值,只要選擇質數 pp 就可以通過 Xi?1Xi?1 得到 XiXi 的值,對于 Xi?1<Xi?p+1Xi?1<Xi?p+1 的值,如果選擇質數 pp,則只能得到 Xi?pXi?p 的值,如果選擇其他質數,由于 pp 是最大的質因數,選擇其他質數能夠改變的增量一定小于 pp,所以 Xi<XiXi′<Xi。但是最小的 Xi?1Xi?1 并不能得到最小的 Xi?2Xi?2,因此對于 X2X2 我們需要枚舉所有可能的 X1X1 的值,來找到最小的 X0X0 的值。

過題代碼

#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cstring> #include <string> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <algorithm> #include <functional> #include <iomanip> using namespace std;#define LL long long const int maxn = 1000000 + 100; int cnt, n; bool vis[maxn]; int prime[maxn];void Prime() {for(int i = 2; i < maxn; ++i) {if(!vis[i]) {prime[cnt++] = i;}for(int j = 0; j < cnt && i < maxn / prime[j]; ++j) {int k = i * prime[j];vis[k] = true;if(i % prime[j] == 0) {break;}}} }int Find(int x) {int ret;int xx = x;for(int i = 0; i < cnt && prime[i] <= xx / prime[i]; ++i) {while(x % prime[i] == 0) {x /= prime[i];ret = prime[i];}}if(x != 1) {ret = x;}return ret; }int main() {#ifdef LOCALfreopen("test.txt", "r", stdin); // freopen("out.txt", "w", stdout);#endif // LOCALios::sync_with_stdio(false);Prime();while(scanf("%d", &n) != EOF) {int Start = Find(n);int ans = INT_MAX;for(int i = n - Start + 1; i <= n; ++i) {int tmp = i - Find(i) + 1;if(tmp >= 3) {ans = min(ans, tmp);}}printf("%d\n", ans);}return 0; }

B. Producing Snow

題意

BobBob 從第 11 天到第 nn 天每天堆體積為 ViVi 體積的雪人,第 ii 天的時候每一個已經堆好的雪人會融化 TiTi 的體積,問在第 ii 天當天所有已經堆好的且沒有完全融化的雪人會融化的總的體積。

輸入

第一行包含一個整數 n (1n105)n (1≤n≤105),第 22 行包含 nn 個整數 V1,V2,?,Vn?(0Vi109)V1,V2,?,Vn(0≤Vi≤109),第 33 行包含 nn 個整數 T1,T2,?,Tn?(0Ti109)T1,T2,?,Tn(0≤Ti≤109)

輸出

輸出 nn 個整數,第 ii 個整數表示第 ii 天融化的雪人體積。

樣例

輸入
3
10 10 5
5 7 2
輸出
5 12 4
提示
第一天堆了一個體積為 1010 的雪人,融化了 55 的體積,剩下一個體積為 55 的雪人,第二天堆了一個體積為 1010 的雪人,每個雪人都融化 77 的體積,第一天的 55 體積的雪人全都融化了,第二天的雪人融化了 77 體積,總共融化了 1212 體積,第二天只剩下一個體積為 33 的雪人,第三天堆了一個體積為 55 的雪人,第二天雪人剩下的體積和第三天雪人的體積都大于等于第三天融化的體積,第三天總共融化了 44 體積的雪人。
輸入
5
30 25 20 15 10
9 10 12 4 13
輸出
9 20 35 11 25

題解

假設第 11 天堆起來的雪人體積為無窮大,那么到第 ii 天的時候這個雪人融化的體積就為 ij=1Tj∑j=1iTj,第 ii 天剛堆起來的雪人沒有受到前 i?1i?1 天融化的影響,但是可以假設這個雪人是從第 11 天堆起來的,第 ii 天的時候融化了 i?1j?1Ti∑j?1i?1Ti 的體積,導致它第 ii 天的體積為 ViVi,因此可以認為這個雪人在第 11 天堆起來的時候的體積為 Vi+i?1j=1TjVi+∑j=1i?1Tj,我們將到第 ii 天的所有雪人的體積都轉化為 Vi=Vi+i?1j=1TjVi′=Vi+∑j=1i?1Tj 后放入 mapmap 中,到第 ii 天完全融化的雪人就是 Vkij=1TjVk′≤∑j=1iTj 的雪人,將這些雪人在第 ii 天融化的體積(Vk?i?1j=1TjVk′?∑j=1i?1Tj)計算出來,然后從 mapmap 中刪去它們,再計算第 ii 天能融化體積 TiTi 的雪人的個數 cntcnt(可以 O(1)O(1) 維護),于是第 ii 天融化的雪人體積就為 (Vj?i?1k=1Tk)+Ti×cnt∑(Vj′?∑k=1i?1Tk)+Ti×cnt,其中 i?1k=1Tk<Vjik=1Tk∑k=1i?1Tk<Vj′≤∑k=1iTk

過題代碼

#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cstring> #include <string> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <algorithm> #include <functional> #include <iomanip> using namespace std;#define LL long long const int maxn = 100000 + 100; int n, cnt; LL mp_cnt; map<LL, int> mp; map<LL, int>::iterator it, itt; LL v[maxn], t[maxn]; map<LL, int>::iterator del[maxn];int main() {#ifdef LOCALfreopen("test.txt", "r", stdin); // freopen("out.txt", "w", stdout);#endif // LOCALios::sync_with_stdio(false);while(scanf("%d", &n) != EOF) {mp_cnt = 0;for(int i = 1; i <= n; ++i) {scanf("%I64d", &v[i]);}for(int i = 1; i <= n; ++i) {scanf("%I64d", &t[i]);t[i] += t[i - 1];}mp.clear();LL ans;for(int i = 1; i <= n; ++i) {ans = 0;cnt = 0;v[i] += t[i - 1];++mp[v[i]];++mp_cnt;it = mp.upper_bound(t[i]);for(itt = mp.begin(); itt != it; ++itt) {ans += ((itt->first) - t[i - 1]) * (itt->second);del[cnt++] = itt;mp_cnt -= itt->second;}for(int j = 0; j < cnt; ++j) {mp.erase(del[j]);}ans += mp_cnt * (t[i] - t[i - 1]);if(i != 1) {printf(" ");}printf("%I64d", ans);}printf("\n");}return 0; }

C. Perfect Security

題意

有兩個長度為 nn 的序列 a1,a2,?,ana1,a2,?,anb1,b2,?,bnb1,b2,?,bn,對于每一個 aiai,在 bb 序列中找到一個數字與其異或,成為新序列的第 ii 個元素 cici,然后從 bb 序列中刪去被選中的數字,求能夠構成的新序列中字典序最小的序列。

輸入

第一行包含一個整數 n (1N3×105)n (1≤N≤3×105),第二行為 nn 個整數 a1,a2,?,an (0ai<230)a1,a2,?,an (0≤ai<230),第三行為 nn 個整數 b1,b2,?,bn (0bi<230)b1,b2,?,bn (0≤bi<230)

輸出

輸出 nn 個整數,第 ii 個整數表示所求新序列的第 ii 項。

樣例

輸入
  • 3
    8 4 13
    17 2 7
    輸出
    10 3 28
    提示
    8?2=108?2=104?7=34?7=313?17=2813?17=28。對于其他可能的答案:(25,6,10),(25,3,15),(10,21,10),(15,21,15),(15,6,28)(25,6,10),(25,3,15),(10,21,10),(15,21,15),(15,6,28),都比 (10,3,28)(10,3,28) 的字典序大。

    輸入
    5
    12 7 87 22 11
    18 39 9 12 16
    輸出
    0 14 69 6 44
    輸入
    10
    331415699 278745619 998190004 423175621 42983144 166555524 843586353 802130100 337889448 685310951
    226011312 266003835 342809544 504667531 529814910 684873393 817026985 844010788 993949858 1031395667
    輸出
    128965467 243912600 4281110 112029883 223689619 76924724 429589 119397893 613490433 362863284

    題解

    將所有 bb 序列中的數字建一棵字典樹,從 11nn 對于每一個 ii,都取一個 bb 序列中與 aiai 異或值最小的,然后將這個數字在字典樹中出現的次數 ?1?1

    過題代碼

    #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cstring> #include <string> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <algorithm> #include <functional> #include <iomanip> using namespace std;#define LL long long const int maxm = 300000 + 100; const int maxn = 300000 * 32 + 100; const int Size = 2; struct Trie {int root, cnt;int val[maxn], tree[maxn][Size];int creat() {++cnt;memset(tree[cnt], 0, sizeof(tree[cnt]));val[cnt] = 0;return cnt;}void Init() {cnt = 0;root = creat();}int id(int x, int dig) {return ((x >> (31 - dig)) & 1);}void add(int x) {int pos = root;for(int i = 0; i < 32; ++i) {int w = id(x, i);if(tree[pos][w] == 0) {tree[pos][w] = creat();}pos = tree[pos][w];++val[pos];}}int query(int x) {int ret = 0;int pos = root;for(int i = 0; i < 32; ++i) {int w = id(x, i);if(tree[pos][w] == 0 || val[tree[pos][w]] == 0) {w = !w;ret |= (1 << (31 - i));}pos = tree[pos][w];--val[pos];}return ret;} }; Trie t; int n, x; int num[maxn];int main() {#ifdef LOCALfreopen("test.txt", "r", stdin); // freopen("out.txt", "w", stdout);#endif // LOCALios::sync_with_stdio(false);while(scanf("%d", &n) != EOF) {t.Init();for(int i = 0; i < n; ++i) {scanf("%d", &num[i]);}for(int i = 0; i < n; ++i) {scanf("%d", &x);t.add(x);}for(int i = 0; i < n; ++i) {if(i != 0) {printf(" ");}printf("%d", t.query(num[i]));}printf("\n");}return 0; }

    總結

    以上是生活随笔為你收集整理的Codeforces Round #470 (Div. 1)的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    • <menu id="asskc"></menu>
        <noframes id="asskc"></noframes>