sam合辑
LCS:裸题直接上。
LCS2:拿每个串去匹配,得到每个结点的最大的答案。
对每个结点取每次匹配的最小值。同时用用每个结点更新pre
答案是每个结点答案去max
bzoj 2555:对每个np记1,然后暴力更新pre(强制在线= =)
然后询问,暴力匹配,失败就是0,成功就是这个点的sz(孩子包括自己的np个数)
bzoj 3988:T=0,每个结点记为1,求个子树和,多了下一位,不多向下(像主席树)
T=1,val[pre] += val[x],同T=0
spojSUBLEX:同3998 T = 0
hdu3518:给代表主串的len个字符l=r=i,用x更新pre,相当于记录每个串的最早出现位置,最迟出现位置,如果每个点的r-l>pre.len,那么长度在min(r-l,lenx)到pre.len+1的之间的都可以成为答案。
hdu4436:多串的建立,每次新串就把last = root,插入一个结点时,如果必须要 !last[s[i]] || ch[last][s[i]] . len != i 才插入这个结点。然后做一遍树p就可以了。
hdu4416,拿每个串去跟主串匹配,求每个结点的max,用结点len键下就行,表示只有大于才不会出现重复
bzoj4032 http://jiruyi910387714.is-programmer.com/posts/90425.html
bzoj 3065 带插入区间K小值
替罪羊套线段树 O(nlog^2n)
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<ctime> #include<cmath> using namespace std; typedef pair<int, int> Pii; typedef long long LL; typedef long double db; #define rep(_,A,B) for(_=A;_<=B;++_) #define repi(_,A,B) for(register int _=A;_<=B;++_) #define FOR(_,A) for(int _=h[A];_;_=next[_]) #define A first #define B second #define mp make_pair char o;template<class O> void read(O&x){while(o=getchar(),o<'0'||o>'9');for(x=o^48;o=getchar(),o>='0'&&o<='9';)x=x*10+(o^48);} const int L = 70005, M = 10000005; const double alpha = 0.8; int n, Q; int a[L], id[L]; struct T { int l, r, s; T(){ l = r = s = 0; } }e[M]; #define mid (l + r >> 1) int rec[M], rec_num, tot; inline int newnode(void) { if(rec_num) { e[rec[rec_num]] = T(); return rec[rec_num--]; } else return ++tot; } void reclaim(int &x) { if(!x) return ; rec[++rec_num] = x; reclaim(e[x].l), reclaim(e[x].r); } void ins(int &x, int l, int r, int y, int f) { if(!x)x = newnode(); e[x].s += f; //cout << "ins : " << x << " " << l << " " << r << " " << y << endl; if(l == r) return ; if(y <= mid) ins(e[x].l, l, mid, y, f); else ins(e[x].r, mid + 1, r, y, f); if(!e[x].s) reclaim(x), x = 0; } int root[L], lc[L], rc[L], Root; void build(int &x, int l, int r) { //cout << "build " << l << " " << r << endl; if(l > r) return ; x = id[mid]; build(lc[x], l, mid - 1), build(rc[x], mid + 1, r); repi(i, l, r) ins(root[x], 0, 70000, a[id[i]], 1);//, cout << "INS " << x << " " << i << endl; } void init(void) { cin >> n; repi(i, 1, n) read(a[i]), id[i] = i; build(Root, 1, n); } int q[L], cnt; void del(int &x) { //cout << "del " << x << endl; if(!x) return ; reclaim(root[x]), root[x] = 0; del(lc[x]); q[++cnt] = x; del(rc[x]); x = 0; } void rebuild(int &x) { //cout << "rebuild : " << x << endl; cnt = 0; del(x); repi(i, 1, cnt) id[i] = q[i];//, cout << id[i] << " "; cout << endl; build(x, 1, cnt); } int tmp; void ins(int &x, int y, int z) { //cout << "ins : " << x << " " << y << " " << z << endl; if(!x) { x = ++n, ins(root[x], 0, 70000, z, 1), a[x] = z; return ;} ins(root[x], 0, 70000, z, 1); int t = e[root[lc[x]]].s; if(y <= t) ins(lc[x], y, z); else ins(rc[x], y - t - 1, z); if(e[root[x]].s * alpha > max(e[root[lc[x]]].s, e[root[rc[x]]].s)) { if(tmp) { //cout << "rc2 " << rc[2] << endl; if(lc[x] == tmp) rebuild(lc[x]); else rebuild(rc[x]); } tmp = 0; } else tmp = x; } int modify(int x, int y, int val) { ins(root[x], 0, 70000, val, 1); //cout << "modify : " << x << " " << y << " " << val << endl; int z, t = e[root[lc[x]]].s; if(y <= t) z = modify(lc[x], y, val); else if(y - 1 == t)z = a[x], a[x] = val; else z = modify(rc[x], y - t - 1, val); ins(root[x], 0, 70000, z, -1); return z; } int q1[L], q2[L], cnt1, cnt2; void query(int x, int l, int r) { //cout << "query " << x << " " << l << " " << r << " "; int l_s = e[root[lc[x]]].s, r_s = e[root[x]].s; //cout << l_s << " " << r_s << endl; if(l == 1 && r == r_s) { q1[++cnt1] = root[x]; /*cout << "q1 " << x << endl;*/ return ; } if(l <= l_s + 1 && l_s + 1 <= r) q2[++cnt2] = a[x];//, cout << "q2 " << x << endl; if(r <= l_s) query(lc[x], l, r); else if(l > l_s + 1) query(rc[x], l - l_s - 1, r - l_s - 1); else { if(l <= l_s) query(lc[x], l, l_s); if(r > l_s + 1) query(rc[x], 1, r - l_s - 1); } } int Query(int x, int y, int k) { cnt1 = cnt2 = 0; query(Root, x, y); int l = 0, r = 70000; while(l < r) { int t = 0; repi(i, 1, cnt1) t += e[e[q1[i]].l].s; repi(i, 1, cnt2) if(l <= q2[i] && q2[i] <= mid) ++t; if(k <= t) { repi(i, 1, cnt1) q1[i] = e[q1[i]].l; r = mid; } else { repi(i, 1, cnt1) q1[i] = e[q1[i]].r; l = mid + 1, k -= t; } } return l; } void work(void) { cin >> Q; char op[5]; int x, y, k, ans = 0; while(Q--) { //cout << "Q rc2 " << Q + 1 << " " << rc[2] << endl; scanf("%s", op); read(x), read(y); x ^= ans, y ^= ans; if(op[0] == 'Q') read(k), printf("%d\n", ans = Query(x, y, k ^ ans)); else if(op[0] == 'M') modify(Root, x, y); else tmp = 0, ins(Root, x - 1, y); } } int main(void) { freopen("3065.in","r",stdin), freopen("3065.out","w",stdout); init(), work(); return 0; }
bzoj 4025: 二分图
对时间分治,用启发式并查集维护一下,时间复杂度O(mlog^2n),然而并查集常数极小,所以跑的比lct的O(mlogn)还快。
lct见http://wuzuofan.is-programmer.com/posts/89928.html 或者 http://c-sunshine.logdown.com
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<ctime> #include<cmath> using namespace std; typedef pair<int, int> Pii; typedef long long LL; typedef long double db; #define rep(_,A,B) for(_=A;_<=B;++_) #define repi(_,A,B) for(register int _=A;_<=B;++_) #define FOR(_,A) for(int _=h[A];_;_=next[_]) #define A first #define B second #define mp make_pair char o;template<class O> void read(O&x){while(o=getchar(),o<'0'||o>'9');for(x=o^48;o=getchar(),o>='0'&&o<='9';)x=x*10+(o^48);} const int L = 100005, M = 200005; int n, m, T; struct M{ int u, v, st, ed; } e[M]; int fa[L], d[L], a[L], q[M], top; Pii findx(int x) { int t = 0; for(; fa[x] != x; x = fa[x]) t ^= a[x]; return mp(x, t); } void merge(int x, int y, int dep) { if(d[x] > d[y]) swap(x, y); if(d[x] == d[y]) ++d[y], q[++top] = -y; fa[x] = y, a[x] = dep, q[++top] = x; } void resume(int t) { for(; top != t; --top) if(q[top] > 0) fa[q[top]] = q[top], a[q[top]] = 0; else --d[-q[top]]; } void init(void) { cin >> n >> m >> T; repi(i, 1, m) { read(e[i].u), read(e[i].v), read(e[i].st), read(e[i].ed), ++e[i].st; if(e[i].st > e[i].ed) --m, --i; } repi(i, 1, n) fa[i] = i, d[i] = 1; } void solve(int l, int r, int r0) { int now = top, mid = l + r >> 1, i, j; rep(i, 1, r0) if(e[i].st <= l && r <= e[i].ed) { Pii x = findx(e[i].u), y = findx(e[i].v); int fx = x.A, fy = y.A, dep = !(x.B ^ y.B); if(fx != fy) merge(fx, fy, dep); else if(dep){ while(l <= r) puts("No"), ++l; resume(now); return ; } swap(e[r0--], e[i--]); } if(l == r) { puts("Yes"); return ; } for(i = 1, j = r0; i <= j; ++i) if(e[i].st > mid) swap(e[i--], e[j--]); solve(l, mid, j); for(i = 1, j = r0; i <= j; ++i) if(e[i].ed <= mid) swap(e[i--], e[j--]); solve(mid + 1, r, j); resume(now); } void work(void) { solve(1, T, m); } int main(void) { freopen("4025.in","r",stdin), freopen("4025.out","w",stdout); init(), work(); return 0; }
首贴膜大爷
orz cjy lzz wlp wzf
orz jzx nxy wyy