分析: 优先队列或者set模拟 然后注意二元组要先排序。。。 赛上因为这个wa了好几发
代码:
// // Created by TaoSama on 2015-09-13 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1.5e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, m, q; char name[N][205]; int val[N]; struct Query { int t, p; Query() {} Query(int t, int p): t(t), p(p) {} bool operator< (const Query& rhs) const { return t < rhs.t; } } A[N]; int Q[N]; bool vis[N]; int ans[N]; void solve(int Max) { set<pair<int, int> > s; int rnk = 0, j = 1; for(int i = 1; i <= m; ++i) { for(; j <= A[i].t; ++j) s.insert(make_pair(val[j], -j)); for(int k = 1; k <= A[i].p; ++k) { if(s.empty()) break; auto iter = s.end(); --iter; if(vis[++rnk]) { ans[rnk] = -iter->second; // printf("%d\n", -iter->second); } if(rnk == Max) return; s.erase(iter); } } for(; j <= n; ++j) s.insert(make_pair(val[j], -j)); while(s.size()) { auto iter = s.end(); --iter; if(vis[++rnk]) { ans[rnk] = -iter->second; // printf("%d\n", -iter->second); } if(rnk == Max) return; s.erase(iter); } } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); while(t--) { scanf("%d%d%d", &n, &m, &q); for(int i = 1; i <= n; ++i) scanf("%s%d", name[i], val + i); for(int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); A[i] = Query(x, y); } sort(A + 1, A + 1 + m); int Max = 0; memset(vis, false, sizeof vis); for(int i = 1; i <= q; ++i) { scanf("%d", Q + i); vis[Q[i]] = true; Max = max(Max, Q[i]); } solve(Max); for(int i = 1; i <= q; ++i) printf("%s%c", name[ans[Q[i]]], " \n"[i == q]); } return 0; }
// // Created by TaoSama on 2015-09-13 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e4 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; const int M = 1e5 + 10; int n, m; int deg[N], val[N]; vector<int> G[N]; bool vis[N]; void dfs(int u, int &cnt, long long& sum) { sum += val[u]; ++cnt; vis[u] = true; for(int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if(vis[v]) continue; dfs(v, cnt, sum); } } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) { scanf("%d", val + i); G[i].clear(); vis[i] = false; deg[i] = 0; } for(int i = 1; i <= m; ++i) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); ++deg[u], ++deg[v]; } queue<int> q; for(int i = 1; i <= n; ++i) if(deg[i] < 2) q.push(i); while(q.size()) { int u = q.front(); q.pop(); deg[u] = 0; vis[u] = true; for(int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if(--deg[v] < 2 && !vis[v]) q.push(v); } } long long ans = 0; for(int i = 1; i <= n; ++i) { if(vis[i]) continue; int cnt = 0; long long sum = 0; dfs(i, cnt, sum); if(cnt & 1) ans += sum; } printf("%I64d\n", ans); } return 0; }
分析: 离线询问 然后并查集 其实就是求连通分量里点的个数 然后求个C_n_2 (a,b) (b,a)算不同的 不除就行了
赛上因为没有按秩合并就莫名跪了好多发 至今不知道为啥
代码:
// // Created by TaoSama on 2015-09-13 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 2e4 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; const int M = 1e5 + 10; int n, m, q; long long ans[5005]; struct Edge { int u, v, c; Edge() {} Edge(int u, int v, int c) : u(u), v(v), c(c) {} bool operator< (const Edge& rhs) const { return c < rhs.c; } } G[M]; struct Query { int d, id; Query() {} Query(int d, int id): d(d), id(id) {} bool operator< (const Query& rhs) const { return d < rhs.d; } } Q[5005]; long long now; int par[N], rnk[N], num[N]; int find(int x) { return par[x] == x ? x : find(par[x]); } void unite(int x, int y) { x = find(x); y = find(y); if(x == y) return; now += num[x] * num[y]; if(rnk[x] < rnk[y]) { par[x] = y; num[y] += num[x]; num[x] = 0; } else { par[y] = x; if(rnk[x] == rnk[y]) ++rnk[x]; num[x] += num[y]; num[y] = 0; } } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); while(t--) { scanf("%d%d%d", &n, &m, &q); for(int i = 0; i < m; ++i) { int u, v, c; scanf("%d%d%d", &u, &v, &c); G[i] = Edge(u, v, c); } sort(G, G + m); for(int i = 0; i < q; ++i) { int x; scanf("%d", &x); Q[i] = Query(x, i); } sort(Q, Q + q); for(int i = 1; i <= n; ++i) { par[i] = i; rnk[i] = 0; num[i] = 1; } memset(ans, 0, sizeof ans); now = 0; for(int i = 0, j = 0; i < q; ++i) { int cur = Q[i].d; while(j < m) { Edge &e = G[j]; if(e.c <= cur) { unite(e.u, e.v); } else break; ++j; } ans[Q[i].id] = now; } for(int i = 0; i < q; ++i) printf("%I64d\n", ans[i] * 2); } return 0; }
分析: 线段树或者ST都行
代码:
// // Created by TaoSama on 2015-09-13 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e3 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, q, dp[2][N][20]; int RMQ(int l, int r) { int k = 31 - __builtin_clz(r - l + 1); int Max = max(dp[1][l][k], dp[1][r - (1 << k) + 1][k]); // int Min = min(dp[0][l][k], dp[0][r - (1 << k) + 1][k]); return Max; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i = 1; i <= n; ++i) { scanf("%d", &dp[0][i][0]); dp[1][i][0] = dp[0][i][0]; } for(int j = 1; (1 << j) <= n; ++j) { for(int i = 1; i + (1 << j) - 1 <= n; ++i) { dp[0][i][j] = min(dp[0][i][j - 1], dp[0][i + (1 << j - 1)][j - 1]); dp[1][i][j] = max(dp[1][i][j - 1], dp[1][i + (1 << j - 1)][j - 1]); } } scanf("%d", &q); while(q--) { int x, y; scanf("%d%d", &x, &y); printf("%d\n", RMQ(x, y)); } } return 0; }
分析: - - 构建二叉树的只是 还是很简单的 O(n^2)可过 集训队里有一个O(nlogn)的建树办法 曾经有过一道10^5数据的题 被下面这个n^2的水过去了
代码:
// // Created by TaoSama on 2015-09-13 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e3 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, q; int sz, ls[N], rs[N], val[N]; int newNode(int x) { ++sz; ls[sz] = rs[sz] = 0; val[sz] = x; return sz; } int insert(int rt, int x) { if(!val[rt]) return newNode(x); if(x < val[rt]) ls[rt] = insert(ls[rt], x); else rs[rt] = insert(rs[rt], x); return rt; } void dfs(int rt, int x) { if(x < val[rt]) { putchar('E'); dfs(ls[rt], x); } else if(x > val[rt]) { putchar('W'); dfs(rs[rt], x); } } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); while(t--) { scanf("%d", &n); sz = 0; memset(val, 0, sizeof val); for(int i = 1; i <= n; ++i) { int x; scanf("%d", &x); insert(1, x); } scanf("%d", &q); while(q--) { int x; scanf("%d", &x); dfs(1, x); puts(""); } } return 0; }
分析: Lucas + CRT模版题 注意CRT合并的时候会炸longlong 需要模拟LL*LL的乘法
代码: 队友写的我贴个板子
// // Created by TaoSama on 2015-09-13 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; const int M = 1e5 + 10; typedef long long ll; ll n, m, k; ll a[12], mm[12]; ll quick_mod(ll a, ll b, ll p) { ll ans = 1; a %= p; while(b) { if(b & 1) ans = ans * a % p; b >>= 1; a = a * a % p; } return ans; } ll C(ll n, ll m, ll p) { if(m > n) return 0; ll ans = 1; for(int i = 1; i <= m; i++) { ll a = (n + i - m) % p; ll b = i % p; ans = ans * (a * quick_mod(b, p - 2, p) % p) % p; } return ans; } ll Lucas(ll n, ll m, ll p) { if(m == 0) return 1; return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p; } ll Extended_Euclid(ll a, ll b, ll &x, ll &y) { ll d; if(b == 0) { x = 1; y = 0; return a; } d = Extended_Euclid(b, a % b, y, x); y -= a / b * x; return d; } ll mod_mul(ll a, ll b, ll mod) { ll ret = 0; while(b) { if(b & 1) ret = (ret + a) % mod; a = (a + a) % mod; b >>= 1; } return ret; } ll CRT() { ll d, x, y, tmp, M, ret; ret = 0; M = 1; for(int i = 0; i < k; i++) M *= mm[i]; for(int i = 0; i < k; i++) { tmp = M / mm[i]; d = Extended_Euclid(mm[i], tmp, x, y); ll temp = mod_mul(y, tmp, M); temp = mod_mul(temp, a[i], M); ret = (ret + temp) % M; //ret=(ret+y*tmp*a[i])%M; } return (M + ret) % M; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n >> m >> k; for(int i = 0; i < k; i++) { cin >> mm[i]; a[i] = Lucas(n, m, mm[i]); } cout << CRT() << endl; } return 0; }