2019ccpc网络赛
B:https://acm.hdu.edu.cn/search.php?field=problem&key=2019�й���ѧ���������ƾ�����CCPC��+-+����ѡ����&source=1&searchmode=source
查询操作询问大于等于 \(k\) 且不在区间\([1, r]\)中 的最小值,强制在线,每个值都不同且范围在 \(1, n\),修改操作单点修改某个值为无穷
询问就是 下标\([r + 1, n + 1]\) 且 \(val >= k\) 和 下标\([1, r]\) 且 \((val >= k 且 修改过)\) 的最小值,显然最大只能是 \(n + 1\) 一定大于\(k\)。
对于修改操作可以看作将原本pos 变为 无穷,值域线段树 ask(1, n + 1)值域中val > r && l >= k的最小值,
维护区间最右端点位置最大值,树上二分
const int maxn = 1e5 + 10;
int a[maxn], p[maxn];
struct seg{
int t[maxn << 2];
#define lr rt << 1
#define rr rt << 1 | 1
#define mid (l + r >> 1)
#define root 1, 1, n
#define lson lr, l, mid
#define rson rr, mid + 1, r
void push(int rt) {
t[rt] = max(t[lr], t[rr]);
}
void build(int rt, int l, int r) {
if(l == r) {
t[rt] = p[l];
return ;
}
build(lson); build(rson);
push(rt);
}
int query(int rt, int l, int r, int R, int k) {
if(l == r) return l;
else if(k > mid) {
if(t[rr] > R) return query(rson, R, k);
else return 0x3f3f3f3f;
}
else {
int res = 0x3f3f3f3f;
if(t[lr] > R) res = query(lson, R, k);
if(res == 0x3f3f3f3f && t[rr] > R) res = query(rson, R, k);
return res;
}
}
void update(int rt, int l, int r, int x) {
if(l == r) {
t[rt] = 0x3f3f3f3f;
return ;
}
if(x <= mid) update(lson, x);
else update(rson, x);
push(rt);
}
}T;
void run() {
int n, m, lastans = 0;
cin >> n >> m;
for(int i = 1; i <= n; ++ i) cin >> a[i], p[a[i]] = i;
n ++; p[n] = n;
T.build(root);
for(int i = 1; i <= m; ++ i) {
int op; cin >> op;
if(op == 1) {
int pos; cin >> pos;
pos ^= lastans;
if(a[pos]) T.update(root, a[pos]), a[pos] = 0;
}
else {
int r, k; cin >> r >> k;
r ^= lastans; k ^= lastans;
lastans = T.query(root, r, k);
cout << lastans << '\n';
}
}
return ;
}
D:
求图中第 \(k\) 小的路径长度
bfs,贪心的找,因为是有向边,对每个点所连边权排序,那么一开始最小的一定是某条边,接下来考虑下一条边的可能,1是可能非这条边拓展来的,那么就在原来的优先队列中,2是这条边拓展来的,那么可能就是当前边\(e(u, v)\),v拓展最小边权的边或者u返回拿取第二小的边,那么通过结构体记录当前拿的是u的第几小的边,每次出边就加两条边进去就行了
const int maxn = 5e4 + 10;
vector<pair<int, int>> g[maxn];
struct node{
int u, v, nxt;
ll val;
node(int u, int v, int nxt, ll val) : u(u), v(v), nxt(nxt), val(val){}
bool operator < (const node &a) const {
return val > a.val;
}
};
int ask[maxn], mx = 0, n, m, q;
ll ans[maxn];
void bfs() {
priority_queue<node> q; int sz = 0;
for(int i = 1; i <= n; ++ i)
if(g[i].size()) q.push({i, g[i][0].second, 0, g[i][0].first});
while(!q.empty()) {
node top = q.top();
q.pop();
ans[++ sz] = top.val;
if(sz == mx) return ;
int u = top.u, v = top.v;
if(g[v].size()) q.push({v, g[v][0].second, 0, g[v][0].first + top.val});
if(top.nxt + 1 < g[u].size()) q.push({u, g[u][top.nxt + 1].second, top.nxt + 1, g[u][top.nxt + 1].first + top.val - g[u][top.nxt].first});
}
return ;
}
void run() {
mx = 0;
cin >> n >> m >> q;
for(int i = 1; i <= n; ++ i) g[i].clear();
for(int i = 1; i <= m; ++ i) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back({w, v});
}
for(int i = 1; i <= n; ++ i) sort(g[i].begin(), g[i].end());
for(int i = 1; i <= q; ++ i) cin >> ask[i], mx = max(mx, ask[i]);
bfs();
for(int i = 1; i <= q; ++ i)
cout << ans[ask[i]] << '\n';
return ;
}

浙公网安备 33010602011771号