比賽開始一個小時纔想起來QwQ,當場寫了ABCnode
#A: P4752 Divided Primeios
平常送分題 注意只留一個非1數判他是否是質數ide
#B: P4753 River Jumpingspa
題意:有跳躍距離下限,求可否通過全部石頭剛好一次跳一個來回code
貪心ci
首先距離河岸最近的兩個石頭必需要能跳上,剩下最多的隔一個跳一個(由於是來回)get
#C: P4754 True Vegetablestring
經典的二分+貪心it
二分最小回合數,把全部菜氣都減去,而後從左到右貪心加,bit維護io
一開始覺得r值沒用,原來r值保證了答案的單調性
題意:小D有個數列 \({a}\) ,當一個數對 \((i,j)(i≤j)\) 知足 \(a_i*a_j \le \max(a_i,a_{i+1},…,a_j)\) ,小D認爲這個數對是美麗的.請你求出美麗的數對的數量。
單調棧處理出每一個值做爲最大值的長度a_x [l,r]
而後對於[l,x]中每一個值\(a_i\),找[x,r]中知足\(a_j \le \frac{a_x}{a_i}\)的數量,這裏能夠用主席樹實現
但這樣複雜度不對,能夠選長度短的一段來枚舉
複雜度 \(T(n) = T(a) + T(n-a-1) + O(n\log n) = O(n\log^2 n),其中a \le n/2\)
問了一下,能夠數歸證實。其實就是啓發式合併
//D #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 1e5+5; int n, a[N], mp[N], m; int st[N], top, l[N], r[N]; void init() { for(int i=1; i<=n; i++) { int le = i; while(top && a[st[top]] <= a[i]) { le = l[st[top]]; r[st[top]] = i-1; top--; } st[++top] = i; l[i] = le; } while(top) r[st[top--]] = n; sort(mp+1, mp+1+n); m = unique(mp+1, mp+1+n) - mp - 1; } struct node { int lc, rc, size; } t[N*18]; int sz, root[N]; void ins(int &x, int l, int r, int p) { t[++sz] = t[x]; x = sz; t[x].size ++; if(l == r) return; int mid = (l+r) >> 1; if(p <= mid) ins(t[x].lc, l, mid, p); else ins(t[x].rc, mid+1, r, p); } int que(int x, int y, int l, int r, int ql, int qr) { if(mp[r] < ql || qr < mp[l]) return 0; if(ql <= mp[l] && mp[r] <= qr) return t[y].size - t[x].size; int mid = (l+r) >> 1, ans = 0; if(ql <= mp[mid]) ans += que(t[x].lc, t[y].lc, l, mid, ql, qr); if(mp[mid] < qr) ans += que(t[x].rc, t[y].rc, mid+1, r, ql, qr); return ans; } long long ans; void solve(int l1, int r1, int l2, int r2, int mid) { for(int i=l1; i<=r1; i++) { int v = a[mid] / a[i]; ans += que(root[l2-1], root[r2], 1, m, 1, v); } } int main() { freopen("in", "r", stdin); ios::sync_with_stdio(false); cin.tie(); cout.tie(); cin >> n; for(int i=1; i<=n; i++) cin >> a[i], mp[i] = a[i]; init(); //for(int i=1; i<=n; i++) printf("hi %d [%d %d]\n", i, l[i], r[i]); for(int i=1; i<=n; i++) { int x = lower_bound(mp+1, mp+1+m, a[i]) - mp; root[i] = root[i-1]; ins(root[i], 1, m, x); } for(int i=1; i<=n; i++) { int le = l[i], ri = r[i]; int d1 = i-le, d2 = ri-i; //if(d1 == 0 || d2 == 0) continue; if(d1 <= d2) solve(le, i, i, ri, i); else solve(i, ri, le, i, i); } cout << ans; }
//A #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> typedef long long ll; using namespace std; const int N = 1e5+5; int n, m, c[N]; ll a[N], b[N], mp[N]; bool is_p(ll n) { for(ll i=2; i*i<=n; i++) if(n%i == 0) return false; return true; } int main() { freopen("in", "r", stdin); ios::sync_with_stdio(false); int T; cin >> T; while(T--) { mp[0] = 0; memset(c, 0, sizeof(c)); cin >> n >> m; for(int i=1; i<=n; i++) cin >> a[i], mp[i] = a[i]; sort(mp+1, mp+1+n); mp[0] = unique(mp+1, mp+1+n) -mp -1; for(int i=1; i<=n; i++) { int x = lower_bound(mp+1, mp+1+mp[0], a[i]) - mp; c[x]++; } for(int i=1; i<=m; i++) { cin >> b[i]; int x = lower_bound(mp+1, mp+1+mp[0], b[i]) - mp; c[x]--; } int cnt = 0; ll ans = 0; for(int i=1; i<=mp[0]; i++) if(mp[i] != 1 && c[i]) { cnt+=c[i]; ans = mp[i]; } if(cnt!=1) puts("NO"); else if(!is_p(ans)) puts("NO"); else puts("YES"); } }
//B #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <vector> typedef long long ll; using namespace std; const int N = 1e5+5; int n, m, s, x[N], vis[N]; vector<int> v; bool solve() { int now = 0; if(x[1] < s) return false; now = 1; vis[1] = 1; v.push_back(1); while(now+2 <= m) { if(x[now+2] - x[now] < s) return false; vis[now+2] = 1; v.push_back(now+2); now += 2; } if(now == m-1) { if(x[m] - x[now] < s) return false; vis[m] = 1; v.push_back(m); now ++; } for(int i=m-1; i>=0; i--) if(!vis[i]) { if(x[now] - x[i] < s) return false; now = i; v.push_back(i); } return true; } int main() { freopen("in", "r", stdin); ios::sync_with_stdio(false); cin >> n >> m >> s; for(int i=1; i<=m; i++) cin >> x[i]; x[0] = 0; x[++m] = n; if(!solve()) cout << "NO" << endl; else { cout << "YES" << endl; for(int i=0; i<v.size(); i++) cout << v[i] << " "; } }
//C #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <vector> typedef long long ll; using namespace std; const int N = 6e5+5; int n, m, k, L, a[N], A[N], r[105], w[N], x[N], v[N]; int c[N]; inline void add(int p, int v) { //printf("add %d %d\n", p, v); cout << endl; for(; p<=n; p+=p&-p) c[p] += v; } inline int sum(int p) { int ans = 0; for(; p; p-=p&-p) ans += c[p]; return ans; } inline void add(int l, int r, int v) { add(l, v); add(r+1, -v); } bool check(int mid) { //printf("check %d\n", mid); for(int i=1; i<=n; i++) a[i] = A[i]; for(int p = 1; p <= m && w[p] <= mid; p++) a[x[p]] -= v[p]; memset(c, 0, sizeof(c)); for(int i=n; i>=1; i--) a[i] -= a[i-1]; for(int i=1; i<=n; i++) add(i, a[i]); int ans = 0; for(int i=1; i<=n; i++) { int x = sum(i); //printf("hi %d %d\n", i, x); if(x < 1) add(i, i+k-1, 1-x), ans += 1-x; } //printf("ans %d\n", ans); return ans <= mid; } int main() { freopen("in", "r", stdin); ios::sync_with_stdio(false); cin >> n >> m >> k >> L; for(int i=1; i<=n; i++) cin >> A[i]; for(int i=1; i<=L; i++) cin >> r[i]; for(int i=1; i<=m; i++) cin >> w[i] >> x[i] >> v[i]; int l = 0, r = 1e8, ans = 0; while(l <= r) { //printf("erfen %d %d\n", l, r); int mid = (l+r) >> 1; if(check(mid)) ans = mid, r = mid-1; else l = mid+1; } cout << ans; }