目錄傳送門
solvedab
cdef
ghij
k5 / 11o-
--o-
o-o-
o對時間分治,線段樹維護可撤銷並查集的模板題。
這樣可以直接維護每乙個時刻的連通性,我們只需要求出當前連通塊的個數、雙方孤立的點數即可得出答案。
所以在增、添邊時維護一下點的度數和孤立點數即可。
code
// author : heyuhhh
// created time : 2020/08/04 09:12:36
#include#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pairpii;
void err(int x)
void err(long long x)
void err(double x)
void err(char x)
void err(const string &x)
void _print()
templatevoid err(const pair&x) ';}
templatevoid err(const t &x) ";}
template void _print(t t, v... v)
#ifdef local
#define dbg(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define dbg(x...)
#endif
//head
const int n = 4e5 + 5;
int n, m, q;
int num, cnt, blosz;
int d[n];
struct ufs sta[n];
void init()
}int find(int x)
bool merge(int u, int v) ;
if (h[x] == h[y]) ++h[y];
sz[y] += sz[x];
f[x] = y;
return true;
}void undo(int k)
}int query(int x)
} ufs;
vectornodes[n << 2];
int ans[n];
void add(int o, int l, int r, int l, int r, pii v)
int mid = (l + r) >> 1;
if (l <= mid)
if (r > mid)
}void dfs(int o, int l, int r)
if (l == r)
int mid = (l + r) >> 1;
dfs(o << 1, l, mid);
dfs(o << 1|1, mid + 1, r);
ufs.undo(cc);
}void run()
}for (int _ = 1; _ <= q; _++) else
}for (auto& it : s)
num = n;
cnt = m;
blosz = n;
dfs(1, 0, q);
for (int i = 1; i <= q; i++)
}int main()
假設我們知道了首項\(x\)以及項數\(m\),那麼我們會發現會對在區間\([(m-2)x+2x+3,(m-2)(x+2)+2x+1]\)即\([mx+3,mx+2m-3]\)的答案嘗試貢獻。
然後觀察有兩點:
接下來就處理第二點。
稍微手模一下就會發現我們可以對區間按照長度對\(4\)取餘進行分類,兩類的貢獻會有不同。
對於模\(4\)為1的區間長度,比如\(1,5,9...\),他們的貢獻類似於\(1,1,2,2,\cdots,2,2,1,1\)這樣對稱的,中間會有個最大值;對於另外一類區間貢獻為\(1,1,2,2,\cdots,t,t,t,\cdots,2,2,1,1\),中間會有三個連續的最大值。
所以根據這個差分一下就行。
**中我用的線段樹維護奇、偶位置的差分,複雜度是兩個log的(列舉\(x,m\)的複雜度是乙個log,是類似於調和級數的,因為是\(m\cdot x\))。
**如下:
code
// author : heyuhhh
// created time : 2020/08/03 13:00:26
#include#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pairpii;
//head
const int n = 1e5 + 5;
const int n = 100001;
ll ans[n];
struct segment_tree
void update(int o, int l, int r, int l, int r, int v)
int mid = (l + r) >> 1;
if(l <= mid) update(o << 1, l, mid, l, r, v);
if(r > mid) update(o << 1|1, mid + 1, r, l, r, v);
}ll res;
void query(int o, int l, int r, int p)
ll query(int p)
}a, b;
void run() else
} else else }}
}for (int i = 1; i < n; i++)
for (int i = 1; i < n; i++)
for (int i = 1; i < n; i++)
int t;
cin >> t;
int _ = 0;
while (t--)
}int main()
直接暴力衝就行。
建圖後對每個連通塊判斷是否存在環即可。
code
// author : heyuhhh
// created time : 2020/08/03 12:14:49
#include#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pairpii;
//head
const int n = 1e5 + 5;
int _;
void run()
if (mp.find(v) == mp.end())
g[mp[u]].push_back(mp[v]);
g[mp[v]].push_back(mp[u]);
++d[mp[u]], ++d[mp[v]];
}vectorvis(tot);
int sum = 0, cnt = 0;
function dfs = [&] (int u) }};
int ans = 0;
for (int i = 0; i < tot; i++) else }}
cout << "case #" << _ << ": ";
cout << ans << '\n';
}int main()
直接貪心,但注意答案可能是\(10^\)會爆long long,然後施展各種奇技淫巧就行。 2020牛客暑期多校訓練營(第八場)
題意 給出n對數,對於每一對,其中如果有沒有選過的數那麼就可以選,就可以選擇那乙個數,ans 需要求最大的ans 思路 隊友很強,思路秒出,十分鐘 一發ac可以把這些數對想成一條邊上的兩個點,可以想像一下如果我要最多的選擇這上面的點,假如這些點構成的邊是一棵樹的話,我們最多在這n個點中能選擇的只有n...
2020牛客暑期多校訓練營(第八場)
總結 這次做的不好,爆零了,雖然確實本場題比較難,但是沒做出來確實問題很大,考慮問題不夠全面仔細。kg 待定給出n對數字a,b。有三種操作。第一種,什麼也不做。第二種,如果ai在在前面沒有被選過,可以選擇ai。第三種,如果bi在前面沒有被選過,可以選擇bi。求最多可以選擇多少種不同的數字。對數字進行...
2020牛客暑期多校訓練營(第八場)
題目鏈結 a all star game 題意 有n個運動員與m個球迷,現給你n個運動員各自的球迷編號,現在問你若要m名球迷都看比賽,至少需要多少名運動員上場?滿足球迷看比賽的條件 1 該球迷喜歡的運動員有上場 2 球迷i與球迷j都有相同的喜歡球員,則球迷j喜歡運動員k,則球迷i也喜歡運動員k 然後...