2020牛客暑期多校訓練營(第三場) 解題報告

2022-05-27 10:15:08 字數 2532 閱讀 6639

溫暖的簽到題。

#include using namespace std;

#define ll long long

ll input()

string s;

int main()

const int n=2e6+7;

int x,ans;

char s[n];

int main()

if(s[i]=='1')

if(s[i]=='2'||s[i]=='3') ans++;

} printf("%d\n",ans+x/2);

}}

溫暖的簽到題。一開始以為是treap裸題,隊友說他會做,就丟給隊友了。賽後發現只有把整個字串想象成乙個環,再定義乙個起始位置在環上滑動就能維護答案了。

#include using namespace std;

#define ll long long

ll input()

const int n=2e6+7;

char s[n];

int main()else

}}

我們找三條比較有特徵的邊,大拇指外側,底側,小指外側長度分別為6,9,8。用叉積判斷點是順時針還是逆時針給出的,然後看順時針/逆時針方向上這三條邊順序,即可判斷左右手。

#include using namespace std;

#define ll long long

ll input()

#define pii pair #define fr first

#define sc second

#define mp make_pair

const int n=27;

pii p[n];

double poly()

return area;

}bool cmp(double a,double b)

double cal(pii a,pii b)

int get(int x)

void solve()

const int n=2e6+7;

ll a[n],dp[n];

int main()

dp[0]=0;

sort(a+1,a+1+n);

for(int i=4;i<=n;i++)

} ll ans=0;

for(int i=1;i<=n;i+=2) ans+=a[i+1]-a[i];

printf("%lld\n",ans+dp[n]);

}}

並查集。看到本題第一想法就是並查集,由於題目中合併兩個集合的條件是兩集合之間的點有邊相連,那麼我們考慮怎樣的點,對增加集合元素有貢獻。

首先已經被掃過的點顯然對答案沒有貢獻,我們發現每次擴充套件出新的點可能對答案會產生貢獻,我們不妨稱之為可擴充套件點或者說是邊界點。對於乙個集合我們可以開乙個佇列儲存有哪些邊界點,每一次向外擴充套件,現當於把佇列內的邊界點取出往外擴充套件一層,並且加入的集合。我們不難發現這個過程有點類似於bfs,其實向外擴充套件一層現當於向外執行一層bfs,因此我們每次往外擴充套件時採用這種類bfs的策略來找到需要合併哪些集合。但是這題卡空間,我們無法開\(8*10^5\)個\(queue \),那麼我們需要手寫用鍊錶實習佇列。

對於集合合併我們必須保持複雜度,必須同時使用路徑壓縮和按秩合併。那麼我們就面臨乙個問題:染色。我們知道在按秩合併的過程中我們無法保證某個集合的顏色為\(o_i\)那麼我們只需要開個陣列或者map維護一下每個集合的顏色就行了(一開始所有集合的顏色都是自己)。

關於此題還有乙個細節需要注意,對於乙個集合\(s_1\)如果其已經被乙個集合\(s\)合併,我們應當認為\(s_1\)是空的,即當\(o_i==s_1\)時該步操作我們無需執行任何操作。具體說明可以見樣例解釋。

#include using namespace std;

#define ll long long

ll input()

#define pb push_back

const int n=8e5+1;

struct node;

struct qu

void push(int x)

end->w=x;

} void pop()

bool empty()

}q[n];

int fa[n],rk[n];

int find(int x)

void merge(int x,int y)else }}

vector g[n];

qu tmp;

map mp;

int n,m;

void solve()

for(int i=1;i<=m;i++)

int qq=input();

for(int i=1;i<=qq;i++)

} mp[find(u)]=tu;

} for(int i=1;i<=n;i++)

}int main()

牛客暑期多校訓練營B Boundary

給定n個點,然後確定乙個過原點的圓,要使這n個點盡可能多的存在與圓上,最後輸出最多的存在於圓上的點的個數 三點確定乙個圓,我們已知這個圓必定經過原點,所以再依次利用三點求圓心的公式列舉每兩個點與原點 三點不共線 確定的圓心,最後選擇確定次數最多的圓心構成的圓 include include incl...

2019牛客暑期多校訓練營(第三場)

目錄 b crazy binary string 思維 d big integer 數論 f planting trees 思維 單調佇列 h magic line 計算幾何 j lru management 模擬 題意 計算最長的01子串和子串行,其中01數量相同。分析 對於子串那麼直接將0製成 ...

牛客暑期多校訓練營2020第4場

題意 給乙個以1為根的樹,定義乙個點的 ancient distance 祖先距離 為該點到最近的被標記的祖先的距離。對於i 1 i n 1 le i le n 1 i n 求標記i個點時,整棵樹上的 ancient distance 的最大值的最小值 設為xi 輸出xi的和。思路 假設已知整棵樹上...