bzoj3514
2016-03-07 17:16
211 查看
lct + 主席树
(这个ntr数组 吼啊 有道(zhe)理 污拉拉。。
姑且就叫ntr算法咯。。
(这个ntr数组 吼啊 有道(zhe)理 污拉拉。。
姑且就叫ntr算法咯。。
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; int n,m,k,ty; int ch[400010][2],fa[400010],rv[400010],x[400010],mi[400010]; int st[400010],tp; struct data { int x,ord; bool operator < (const data &b)const { return x < b.x; } }ntr[200010]; struct edge { int u,v; }e[200010]; int head[200010]; struct seg { int ls,rs,l,r,sum; }tr[4400010]; int cnt; int rt[200010],last; int read_int () { char c = getchar(); int re = 0; for(;c > '9' || c < '0';c = getchar()); for(;c >= '0' && c <= '9';c = getchar()) re = re * 10 + c - '0'; return re; } int find (int u) { if(u == head[u]) return u; return head[u] = find(head[u]); } void pu (int u) { mi[u] = x[u]; mi[u] = min(mi[u],mi[ch[u][1]]); mi[u] = min(mi[u],mi[ch[u][0]]); } void reverse (int u) { int t = ch[u][0]; ch[u][0] = ch[u][1]; ch[u][1] = t; rv[u] ^= 1; } void pd (int u) { if(!rv[u]) return; rv[u] = 0; reverse(ch[u][0]); reverse(ch[u][1]); } void rot (int u,int d) { ch[fa[u]][d ^ 1] = ch[u][d]; if(ch[u][d]) fa[ch[u][d]] = fa[u]; int t = fa[fa[u]]; fa[fa[u]] = u; ch[u][d] = fa[u]; fa[u] = t; pu(ch[u][d]); pu(u); if(!t) return; if(ch[t][0] == ch[u][d]) ch[t][0] = u; if(ch[t][1] == ch[u][d]) ch[t][1] = u; } void splay (int u) { st[tp = 1] = u; int t = u; while(ch[fa[t]][0] == t || ch[fa[t]][1] == t) { t = fa[t]; st[++tp] = t; } while(tp) pd(st[tp--]); while(ch[fa[u]][0] == u || ch[fa[u]][1] == u) { if(ch[fa[fa[u]]][0] != fa[u] && ch[fa[fa[u]]][1] != fa[u]) { if(ch[fa[u]][0] == u) rot(u,1); else rot(u,0); } else { int d = ch[fa[fa[u]]][0] == fa[u]; if(ch[fa[u]][d] == u) { rot(u,d ^ 1); rot(u,d); } else { rot(u,d); rot(u,d); } } } } void access (int u) { int v = 0; while(u) { splay(u); ch[u][1] = v; pu(u); v = u; u = fa[u]; } } void mtr (int u) { access(u); splay(u); reverse(u); } void link (int u,int v) { mtr(u); mtr(v); fa[u] = v; } void cut (int u,int v) { mtr(v); access(v); splay(u); fa[u] = 0; } void push_up (int M) { tr[M].sum = tr[tr[M].ls].sum + tr[tr[M].rs].sum; } void build_ori (int l,int r,int M) { tr[M].l = l; tr[M].r = r; if(l == r) return; int mid = (l + r) / 2; tr[M].ls = ++cnt; build_ori(l,mid,tr[M].ls); tr[M].rs = ++cnt; build_ori(mid + 1,r,tr[M].rs); } void build (int last,int ord,int M) { tr[M].l = tr[last].l; tr[M].r = tr[last].r; if(tr[M].l == tr[M].r) { tr[M].sum = 1; return; } int mid = (tr[M].r + tr[M].l) / 2; if(ord > mid) { tr[M].ls = tr[last].ls; tr[M].rs = ++cnt; build(tr[last].rs,ord,tr[M].rs); } else { tr[M].rs = tr[last].rs; tr[M].ls = ++cnt; build(tr[last].ls,ord,tr[M].ls); } push_up(M); } int find_ans (int l,int r,int M) { if(l == tr[M].l && tr[M].r == r) return tr[M].sum; int mid = (tr[M].l + tr[M].r) / 2; if(l > mid) return find_ans(l,r,tr[M].rs); else { if(r <= mid) return find_ans(l,r,tr[M].ls); else return find_ans(l,mid,tr[M].ls) + find_ans(mid + 1,r,tr[M].rs); } } int main () { n = read_int(); m = read_int(); k = read_int(); ty = read_int(); for(int i = 0;i <= n;++i) { x[i] = mi[i] = 0x3f3f3f3f; head[i] = i; } for(int i = 1;i <= m;++i) { ntr[i].ord = i; e[i].u = read_int(); e[i].v = read_int(); if(e[i].u == e[i].v) { ntr[i].x = i; continue; } if(find(e[i].u) == find(e[i].v)) { mtr(e[i].u); access(e[i].v); splay(e[i].u); ntr[i].x = mi[e[i].u]; cut(e[ntr[i].x].u,ntr[i].x + n); cut(e[ntr[i].x].v,ntr[i].x + n); } else head[find(e[i].u)] = find(e[i].v); x[n + i] = mi[n + i] = i; link(n + i,e[i].u); link(n + i,e[i].v); } sort(ntr + 1,ntr + 1 + m); rt[0] = last = cnt = 1; build_ori(1,m,1); for(int i = 1;i <= m;++i) { if(ntr[i].x != ntr[i - 1].x) { for(int j = ntr[i - 1].x + 1;j < ntr[i].x;++j) rt[j] = last; } build(last,ntr[i].ord,rt[ntr[i].x] = ++cnt); last = rt[ntr[i].x]; } for(int i = ntr[m].x + 1;i <= m;++i) { rt[i] = last; } int L,R,ans = 0; for(int i = 1;i <= k;++i) { L = read_int(); R = read_int(); if(ty) { L ^= ans; R ^= ans; } ans = n - find_ans(L,R,rt[L - 1]); printf("%d\n",ans); } return 0; }
相关文章推荐
- MySQLdb模块 类操作方法
- Android中的缓存机制与实现
- 面向对象之开闭原则
- Ext入门学习系列(四)面板控件
- jmeter测试https
- MySQL索引设计原则
- Android Studio当中配置Open CV
- 多节点Kubernetes安装
- 关于类中方法的调用
- vim字符串替换
- Ext入门学习系列(五)表格控件(3)
- 【mark】App Widget设计
- jQuery 读取 JSONArray 的方法
- 求正整数各位数字之和
- centos 7 源码安装MySQL-5.6.20
- 【周练2016.3.7】B - Lucky Numbers(位运算,水)
- 面试经验(妙计旅行:C++算法工程师)
- cocosjs模态对话框
- 杂题 SPOJ MOBILE2 - Mobiles
- x264代码剖析(三):主函数main()、解析函数parse()与编码函数encode()