巷北

orz 各位神犇

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