牛客NOIP提高組(三)題解

来源:https://www.cnblogs.com/zwfymqz/archive/2018/09/26/9704941.html
-Advertisement-
Play Games

心路歷程 預計得分:$30 + 0 + 0 = 30$ 實際得分:$0+0+0= 0$ T1算概率的時候沒模爆long long了。。。 A 我敢打賭這不是noip難度。。。 考慮算一個位置的概率,若想要$k$步把它幹掉,那麼與他距離為$1$到$k - 1$的點都必須阻塞 且距離為$k$的點至少有一 ...


心路歷程

預計得分:$30 + 0 + 0 = 30$

實際得分:$0+0+0= 0$

T1算概率的時候沒模爆long long了。。。

A

我敢打賭這不是noip難度。。。

考慮算一個位置的概率,若想要$k$步把它幹掉,那麼與他距離為$1$到$k - 1$的點都必須阻塞

且距離為$k$的點至少有一個沒被阻塞

概率的處理可以用首碼和優化。

這樣看似是$O(n^3 logn)$,但是卻不能通過,考慮在首碼和處理的時候有很多沒用的狀態(超出邊界)

加一些剪枝即可

#include<cstdio>
#define max(a, b) (a < b ? b : a)
#define LL long long
using namespace std;
const int MAXN = 201, mod = 1e9 + 7, INF = 1e9 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, a[MAXN][MAXN], g[MAXN][MAXN][MAXN], vis[MAXN][MAXN];
LL fastpow(LL a, LL p) {
    LL base = 1;
    while(p) {
        if(p & 1) base = 1ll * base * a % mod;
        a = 1ll * a * a % mod; p >>= 1;
    }
    return base;
}
LL inv(LL a) {
    return fastpow(a, mod - 2);
}
int mul(int a, int b) {
    if(1ll * a * b > mod) return 1ll * a * b % mod;
    else return a * b;
}
void Pre() {
    //cout << a[1][1] << endl;
    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= M; j++)
            g[0][i][j] = a[i][j] % mod;
 
    for(int k = 1; k <= max(N, M); k++)
        for(int i = 1; i <= N; i++)
            for(int j = 1; j <= M; j++) {
                if((i - k < 0) || (j - k < 0) || (i + k > N + 1) || (j + k > M + 1)) {vis[i][j] = 1; continue;}
                if(vis[i][j]) continue;
                g[k][i][j] = mul(g[k - 1][i - 1][j], g[k - 1][i + 1][j]);
                if(k > 2) g[k][i][j] = mul(g[k][i][j], inv(g[k - 2][i][j]));
                if(k >= 2) g[k][i][j] = mul(mul(g[k][i][j], inv(a[i][j + k - 2])), inv(a[i][j - k + 2]));
                g[k][i][j] = mul(mul(g[k][i][j], a[i][j + k]), a[i][j - k]);
            }
}
LL calc(int x, int y) {
    LL ans = 0, s = a[x][y];
    for(int i = 1; i <= max(N, M); i++) {
        if((x - i < 0) || (y - i < 0) || (x + i > N + 1) || (y + i > M + 1)) break;
        int now = g[i][x][y];
        ans = (ans + mul(mul(i, (1 - now + mod)), s)) % mod;
        s = mul(s, now);
    }
    return ans;
}
int main() {
//  freopen("a.in", "r", stdin);
    N = read(); M = read();
    for(LL i = 1; i <= N; i++) {
        for(LL j = 1; j <= M; j++) {
            LL x = read(), y = read();
            a[i][j] = mul(x, inv(y));
        }
    }
    Pre();
    for(LL i = 1; i <= N; i++, puts(""))
        for(LL j = 1; j <= M; j++)
            printf("%lld ", calc(i, j) % mod);
    return 0;
}
A

 

B

考場上根本就沒時間做。。

題目給出的模型太難處理了,考慮轉化成一個較為普通的模型

遇到這種每個點有兩個狀態的題不難想到拆點,分別表示贏 / 輸

當$a$贏了$b$,就從$a$贏向$b$輸連邊。

這樣會得到一個新的無環圖,可以證明,兩個圖中的環是等價的。

直接暴力找最小環即可,時間複雜度:$O(n^2 T)$

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 10005, BIT = 13;
int N, M, dep[MAXN], fa[MAXN][21], MC, U, V;
vector<int> v[MAXN];
int LCA(int x, int y) {
    if(dep[x] < dep[y]) swap(x, y);
    for(int i = BIT; i >= 0; i--) if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
    if(x == y) return x;
    for(int i = BIT; i >= 0; i--) if(fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
    return fa[x][0];
}
void bfs(int x) {
    queue<int> q;
    q.push(x); dep[x] = 1; fa[x][0] = 0;
    while(!q.empty()) {
        int p = q.front(); q.pop();
        for(int i = 0, to; i < v[p].size(); i++) {
            if(!dep[to = v[p][i]]) {
                fa[to][0] = p; dep[to] = dep[p] + 1;
                for(int j = 1; j <= BIT; j++) fa[to][j] = fa[fa[to][j - 1]][j - 1];
                q.push(to);
            }
            else if(to != fa[p][0]) {
                int lca = LCA(p, to), dis = dep[p] + dep[to] - 2 * dep[lca] + 1;
                if(dis < MC) MC = dis, U = p, V = to;
            }
        }
    }
}
int main() {
    int meiyong; scanf("%d", &meiyong);
    while(scanf("%d", &N) && N) {//tag
        scanf("%d", &M);
           
        MC = MAXN;
        for(int i = 1; i <= 2 * N; i++) v[i].clear();
        memset(dep, 0, sizeof(dep));
        memset(fa, 0, sizeof(fa));
           
        for(int i = 1; i <= M; i++) {
            int x, y; scanf("%d %d", &x, &y);
            v[x].push_back(y + N); v[y + N].push_back(x);
        }
           
        for(int i = 1; i <= 2 * N; i++) if(!dep[i]) bfs(i);
        if(MC == MAXN) {puts("-1");continue;}
        int lca = LCA(U, V);
        vector<int> ans; ans.clear();
        printf("%d\n", MC);
        while(U != lca) printf("%d ", (U - 1) % N + 1), U = fa[U][0];
        printf("%d", (lca - 1) % N + 1);
        while(V != lca) ans.push_back((V - 1) % N + 1), V = fa[V][0];
        for(int i = ans.size() - 1; i >= 0; i--) printf(" %d", ans[i]);
        puts("");
    }
    return 0;
}
/*
*/
B

C

$k=2$的時候是斐波那契博弈

$k \not = 2$的時候是神仙結論

考慮$k \not = 2$怎麼做。

結論:

若$l = n$時先手必輸,那麼我們找到一個$m = \frac{n}{k} >= n$,且最小的$m$,當$l = n+m$先手也一定必輸

證明:

我們把多著的$m$個單獨考慮,若$n < l < n+m$時,先手拿走多餘的$m$個,後手必敗。

但當$l = n +m$時,先手不能拿走$m$個,因為此時後手可以一步拿走剩餘的。

不斷往下推就行了

#include<bits/stdc++.h>
#define LL long long  
using namespace std;
const int MAXN = 1e7 + 10;
int T, k, top;
LL l, sta[MAXN];
int main() {
    cin >> T;
    while(T--) {
        cin >> k >> l;
        LL now = 1;
        sta[top = 1] = 1;
        while(now < l) {
            int nxt = lower_bound(sta + 1, sta + top + 1, (now % k == 0) ? now / k : (now / k + 1)) - sta;
            sta[++top] = (now = (now + sta[nxt]));
        }
        puts(now == l ? "DOG" : "GOD");
    }
    return 0;
}
/*
1
2 21
*/
C

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 現在許多的主流網站都將'#'大規模用於重要URL中,我們通過正則和window.location.search獲取參數已經行不通了。 ...
  • 1 2 省/市: 3 市/區: 4 5 運行: ...
  • 開篇先來一張圖 下圖是官方展示的生命周期圖 Vue實例的生命周期鉤子函數(8個) 1. beforeCreate 剛 new了一個組件,無法訪問到數據和真實的dom,基本上這個好像不能幹啥 2. created data屬性完成了賦值,可以對數據進行修改但是不會觸發updated,在這裡可以做初始數 ...
  • 因為公司項目要用vue框架,所以會用vue-cli來新建項目。用過vue的都知道,要全局安裝vue以及腳手架vue-cli,然後執行vue init webpack projectname來新建vue項目模板。但是最近新建項目的時候發現,即使是在本機全局安裝了vue最新版本2.5.17,可是用vue ...
  • 當兩個盒子都設置display: inline-block之後並且css也清除了預設樣式 這時候會發現div盒子之間仍然存在間隙 將font-size清0間距就會取消 ...
  • 關於保存列表表頭的配置,一般我們不需要與後臺交互,直接保存在 localStorage 中就能滿足常規使用需求(需要瀏覽器支持)。 直接上代碼,插件: 如何使用:由於這是一個比較常規的需求,因此這裡預設給所有的gridPanel配置此插件,並支持手動配置參數禁用之,考慮覆寫gridPanel類。 代 ...
  • /** * 為指定控制項添加限制性事件, 該事件在觸發之後, 會被移除, 併在指定的時間間隔後, 重新綁定, 適用於避免控制項事件被誤操作重覆觸發的場景 * @param {String} domID 要添加事件的控制項ID * @param {String} eventName 要添加的事件, 例如: ...
  • vue實現簡單的雙向綁定的原理 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...