离线强化训练

Posted Algorithms Crush Me

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了离线强化训练相关的知识,希望对你有一定的参考价值。

10.17

HYSBZ - 4999

看似在线,实际每个数字独立,可以每种数字拆出来考虑,转变为树上单点修改询问链。

维护差分,变为子树修改,单点询问,排好dfs序后用线段树维护。

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <vector>
  4 #include <algorithm>
  5 #include <set>
  6 using namespace std;
  7 const int maxn = 1e5 + 10;
  8 int a[maxn], c[maxn];
  9 vector<int> b, g[maxn];
 10 int op[200005], I[200005], J[200005], X[200005], ans[200005];
 11 
 12 typedef pair<int, int> pii;
 13 vector<pii> q[300005];
 14 set<int> S;
 15 set<int> :: iterator it;
 16 
 17 // LCA
 18 int dfs_clock = 0;
 19 int dep[maxn], l[maxn], r[maxn];
 20 int anc[maxn][33];
 21 void dfs(int x, int fa)
 22 {
 23     l[x] = r[x] = ++dfs_clock;
 24     for(int i = 0; i < g[x].size(); i++)
 25     {
 26         int to = g[x][i];
 27         if(to == fa) continue;
 28         dep[to] = dep[x] + 1;
 29         anc[to][0] = x;
 30         dfs(to, x);
 31         r[x] = r[to];
 32     }
 33 }
 34 void LCA_init(int n)
 35 {
 36     for(int j = 1; (1 << j) < n; j++)
 37         for(int i = 1; i <= n; i++) if(anc[i][j-1])
 38             anc[i][j] = anc[anc[i][j-1]][j-1];
 39 }
 40 int LCA(int u, int v)
 41 {
 42     int log;
 43     if(dep[u] < dep[v]) swap(u, v);
 44     for(log = 0; (1 << log) < dep[u]; log++);
 45     for(int i = log; i >= 0; i--)
 46         if(dep[u] - (1<<i) >= dep[v]) u = anc[u][i];
 47     if(u == v) return u;
 48     for(int i = log; i >= 0; i--)
 49         if(anc[u][i] && anc[u][i] != anc[v][i])
 50             u = anc[u][i], v = anc[v][i];
 51     return anc[u][0];
 52 }
 53 
 54 // segment_tree
 55 int tag[maxn<<2];
 56 void modify(int p, int tl, int tr, int l, int r, int x)
 57 {
 58     if(tr < l || r < tl) return;
 59     if(l <= tl && tr <= r)
 60     {
 61         tag[p] += x;
 62         return;
 63     }
 64     int mid = (tl + tr) >> 1;
 65     modify(p<<1, tl, mid, l, r, x);
 66     modify(p<<1|1, mid+1, tr, l, r, x);
 67 }
 68 int query(int p, int tl, int tr, int x)
 69 {
 70     if(x == 0) return 0;
 71     int ret = tag[p];
 72     if(tl == tr) return ret;
 73     int mid = (tl + tr) >> 1;
 74     if(x <= mid) ret += query(p<<1, tl, mid, x);
 75     else ret += query(p<<1|1, mid+1, tr, x);
 76     return ret;
 77 }
 78 
 79 int main(void)
 80 {
 81     int N, Q;
 82     scanf("%d %d", &N, &Q);
 83     for(int i = 1; i <= N; i++) scanf("%d", a + i), b.push_back(a[i]);
 84     for(int i = 1; i < N; i++)
 85     {
 86         int u, v;
 87         scanf("%d %d", &u, &v);
 88         g[u].push_back(v);
 89         g[v].push_back(u);
 90     }
 91     for(int i = 1; i <= Q; i++)
 92     {
 93         char s[11];
 94         scanf("%s", s);
 95         if(s[0] == C)
 96         {
 97             op[i] = 1;
 98             scanf("%d %d", I + i, X + i);
 99         }
100         else
101         {
102             op[i] = 2;
103             scanf("%d %d %d", I + i, J + i, X + i);
104         }
105         b.push_back(X[i]);
106     }
107     sort(b.begin(), b.end());
108     b.erase(unique(b.begin(), b.end()), b.end());
109     for(int i = 1; i <= N; i++) a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;
110     for(int i = 1; i <= Q; i++) X[i] = lower_bound(b.begin(), b.end(), X[i]) - b.begin() + 1;
111     for(int i = 1; i <= N; i++) c[i] = a[i], q[c[i]].push_back(pii(1, i));
112     for(int i = 1; i <= Q; i++)
113     {
114         if(op[i] == 1)
115         {
116             q[c[I[i]]].push_back(pii(-1, I[i]));
117             q[X[i]].push_back(pii(1, I[i]));
118             c[I[i]] = X[i];
119         }
120         else q[X[i]].push_back(pii(0, i));
121     }
122     dfs(1, 0);
123     LCA_init(N);
124     for(int i = 1; i <= b.size(); i++)
125     {
126         for(int j = 0; j < q[i].size(); j++)
127         {
128             int x = q[i][j].first, y = q[i][j].second;
129             if(x == 1) modify(1, 1, N, l[y], r[y], 1), S.insert(y);
130             if(x == -1) modify(1, 1, N, l[y], r[y], -1), S.erase(y);
131             if(x == 0) ans[y] = query(1, 1, N, l[I[y]]) + query(1, 1, N, l[J[y]]) - query(1, 1, N, l[LCA(I[y], J[y])]) - query(1, 1, N, l[anc[LCA(I[y], J[y])][0]]);
132         }
133         for(it = S.begin(); it != S.end(); it++) modify(1, 1, N, l[*it], r[*it], -1);
134         S.clear();
135     }
136     for(int i = 1; i <= Q; i++)
137         if(op[i] == 2) printf("%d\n", ans[i]);
138     return 0;
139 }
Aguin

 

以上是关于离线强化训练的主要内容,如果未能解决你的问题,请参考以下文章

轻松解决TSP问题之强化学习(BaseLine)

强化学习系列12:使用julia训练深度强化模型

监督学习 vs. 监督学习离线(批量)强化学习

关于nessus的离线更新(强化记忆)

离线强化学习的乐观观点

白话强化学习(理论+代码)