模板

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 const int maxm=50100;
  5 const int maxn=500;
  6 char ch[200];
  7 int t,to[maxm],head[maxn],nex[maxm],tot;
  8 
  9 
 10 
 11 struct Blossom {
 12     int p[maxn], vi[maxn], tag, fl[maxn], c[maxn], pr[maxn], q[maxn], r;
 13     int find(int x) {
 14         return x == p[x] ? x : p[x] = find(p[x]);
 15     }
 16     void add(int u, int v) {
 17         t++;
 18         to[t] = v;
 19         nex[t] = head[u];
 20         head[u] = t;
 21     }
 22     int lca(int u, int v) {
 23         ++tag;
 24         u = find(u);
 25         v = find(v);
 26         for (;; swap(u, v))
 27             if (u) {
 28                 if (fl[u] == tag) return u;
 29                 fl[u] = tag;
 30                 u = find(pr[c[u]]);
 31             }
 32     }
 33     void blo(int u, int v, int l) {
 34         for (; find(u) != l; v = c[u], u = pr[v]) {
 35             pr[u] = v;
 36             if (vi[c[u]] == 1)
 37                 vi[q[++r] = c[u]] = 0;
 38             if (find(u) == u) p[u] = l;
 39             if (find(c[u]) == c[u]) p[c[u]] = l;
 40         }
 41 
 42     }
 43     bool aug(int s) {
 44         for (int i = 1; i <= tot; i++) {
 45             p[i] = i;
 46             vi[i] = -1;
 47         }
 48         vi[q[r = 1] = s] = 0;
 49         int x, y;
 50         for (int i = 1; i <= r; i++)
 51             for (int j = head[x = q[i]]; j; j = nex[j])
 52                 if (vi[y = to[j]] == -1) {
 53                     pr[y] = x;
 54                     vi[y] = 1;
 55                     if (!c[y]) {
 56                         for (int u = x, v = y, t; u; v = t, u = pr[v]) {
 57                             t = c[u];
 58                             c[u] = v;
 59                             c[v] = u;
 60                         }
 61                         return 1;
 62                     }
 63                     vi[q[++r] = c[y]] = 0;
 64                 } else if (!vi[y] && find(x) != find(y)) {
 65                     int l = lca(x, y);
 66                     blo(x, y, l);
 67                     blo(y, x, l);
 68                 }
 69         return 0;
 70     }
 71     void init() {
 72         t = 0;
 73         memset(head, 0, sizeof(head));
 74         memset(c, 0, sizeof(c));
 75         memset(pr, 0, sizeof(pr));
 76     }
 77 };
 78 int main() {
 79     int _, n, m;
 80     scanf("%d", &_);
 81     while (_--) {
 82         Blossom blossom;
 83         blossom.init();
 84         scanf("%d%d", &n, &m);
 85         tot = n * 2 + m;
 86         for (int i = 1; i <= n; i++) {
 87             scanf("%s", ch + 1);
 88             blossom.add(i + m, i + m + n);
 89             blossom.add(i + m + n, i + m);
 90             for (int j = 1; j <= m; j++)
 91                 if (ch[j] - '0') {
 92                     blossom.add(j, i + m);
 93                     blossom.add(i + m, j);
 94                     blossom.add(j, i + m + n);
 95                     blossom.add(i + m + n, j);
 96                 }
 97         }
 98         int ans = 0;
 99         for (int i = 1; i <= tot; i++) {
100             if (!blossom.c[i]) ans += blossom.aug(i);
101         }
102         printf("%d\n", ans - n);
103     }
104     return 0;
105 }
View Code

 array

不难看出对于每次2操作,答案最大是n+1(因为每次更新是+10000000, 永远不会占用n+1,而且k是保证<=n的). 如果某个数字被进行过1操作, 那么就代表这个数字可以用于2类操作的查询,把这个数字加到set里.对于找2类询问的答案,第一种是从a[r+1,n]里找>=k的最小值(主席树实现),第二种是从这个set里找>=k的最小值(对set进行二分查找),取两者间最小值即可.

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=200100;
 4 struct node
 5 {
 6     int l,r,sum;
 7 } hjt[maxn*40];
 8 int cnt,root[maxn*20],n,m,book[maxn];
 9 int a[maxn];
10 set<int>s;
11 set<int>::iterator it;
12 void init() {
13     for (int i = 0; i <= n; i++) book[i] = 0;
14     s.clear();
15     root[0] = 0;
16     cnt = 0;
17     for (int i = 0; i < maxn * 20; i++) hjt[i].l = hjt[i].r = hjt[i].sum = 0;
18 }
19 void insert(int l,int r,int pre,int &now,int p)
20 {
21     hjt[++cnt]=hjt[pre];
22     now=cnt;
23     hjt[now].sum++;
24     if (l==r)
25     {
26         return;
27     }
28     int mid=(l+r)>>1;
29     if (p<=mid)
30     {
31         insert(l,mid,hjt[pre].l,hjt[now].l,p);
32     }
33     else
34     {
35         insert(mid+1,r,hjt[pre].r,hjt[now].r,p);
36     }
37 }
38 int query(int rt,int l,int r,int L,int R) {
39     if (R < L) return -1;
40     if (!rt) return -1;
41     if (!hjt[rt].sum) return -1;
42     if (l >= L && r <= R) {
43         if (l == r)
44             return l;
45         else {
46             int mid = (l + r) >> 1;
47             int res = -1;
48             if (L <= mid) res = query(hjt[rt].l, l, mid, L, R);
49             if (R > mid && res == -1) res = query(hjt[rt].r, mid + 1, r, L, R);
50             return res;
51         }
52     }
53     int mid = (l + r) >> 1;
54     int res = -1;
55     if (L <= mid) res = query(hjt[rt].l, l, mid, L, R);
56     if (R > mid && res == -1) res = query(hjt[rt].r, mid + 1, r, L, R);
57     return res;
58 }
59  
60 int main() {
61     int _;
62     scanf("%d", &_);
63     while (_--) {
64         scanf("%d%d", &n, &m);
65         init();
66         root[n + 1] = 0;
67         for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
68         for (int i = n; i >= 1; i--)
69             insert(1, n, root[i + 1], root[i], a[i]);
70         int lastans = 0;
71         for (int i = 1; i <= m; i++) {
72             int id;
73             scanf("%d", &id);
74             if (id == 1) {
75                 int t;
76                 scanf("%d", &t);
77                 int pos = t ^lastans;
78                 if (book[pos]) continue;
79                 book[pos] = 1;
80                 s.insert(a[pos]);
81             } else {
82                 int t1, t2;
83                 scanf("%d%d", &t1, &t2);
84                 int R = (t1 ^lastans) + 1;
85                 int k = t2 ^lastans;
86                 int ans = n + 1;
87                 it = s.lower_bound(k);
88                 if (it != s.end()) ans = *it;
89                 if (R <= n) {
90                     t1 = query(root[R], 1, n, k, n);
91                     if (t1 != -1) ans = min(ans, t1);
92                 }
93                 printf("%d\n", ans);
94                 lastans = ans;
95             }
96         }
97     }
98     return 0;
99 }
View Code

主席树(静态查询区间第k大)

 1 #include <bits/stdc++.h>
 2  
 3 using namespace std;
 4 const int maxn=200100;
 5 struct node
 6 {
 7     int l,r,sum;
 8 } hjt[maxn*40];
 9 int cnt,root[maxn*40];
10 vector<int>v;
11 int a[maxn];
12 int getid(int x)
13 {
14     return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
15 }
16  
17 void insert(int l,int r,int pre,int &now,int p)
18 {
19     hjt[++cnt]=hjt[pre];
20     now=cnt;
21     hjt[now].sum++;
22     if (l==r)
23     {
24         return;
25     }
26     int mid=(l+r)>>1;
27     if (p<=mid)
28     {
29         insert(l,mid,hjt[pre].l,hjt[now].l,p);
30     }
31     else
32     {
33         insert(mid+1,r,hjt[pre].r,hjt[now].r,p);
34     }
35 }
36  
37 int query(int l,int r,int L,int R,int k)
38 {
39     if (l==r)
40         return l;
41     int mid=(l+r)>>1;
42     int tmp=hjt[hjt[R].l].sum-hjt[hjt[L].l].sum;
43     if (k<=tmp)
44     {
45         return query(l,mid,hjt[L].l,hjt[R].l,k);
46     }
47     else
48     {
49         return query(mid+1,r,hjt[L].r,hjt[R].r,k-tmp);
50     }
51 }
52 int main()
53 {
54     int n,m;
55     scanf("%d%d",&n,&m);
56     for (int i=1; i<=n; i++)
57     {
58         scanf("%d",&a[i]);
59         v.push_back(a[i]);
60     }
61     sort(v.begin(),v.end());
62     v.erase(unique(v.begin(),v.end()),v.end());
63     for (int i=1; i<=n; i++)
64     {
65         insert(1,n,root[i-1],root[i],getid(a[i]));
66     }
67     while (m--)
68     {
69         int l,r,k;
70         scanf("%d%d%d",&l,&r,&k);
71         printf("%d\n",v[query(1,n,root[l-1],root[r],k)-1]);
72     }
73     return 0;
74 }
View Code

最近公共祖先(LCA)  

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=500010;
 4 struct node
 5 {
 6     int n,t;
 7 } e[N*2];
 8 int h[N],f[N][20],t,d[N],x,y;
 9 void add(int u,int v)
10 {
11     t++;
12     e[t].t=v;
13     e[t].n=h[u];
14     h[u]=t;
15 }
16 
17 void dfs(int x,int fa)
18 {
19     d[x]=d[fa]+1;
20     f[x][0]=fa;
21     for (int i=1; (1<<i)<=d[x]; i++)
22     {
23         f[x][i]=f[f[x][i-1]][i-1];
24     }
25     for (int i=h[x]; i; i=e[i].n)
26     {
27         if (e[i].t!=fa)
28         {
29             dfs(e[i].t,x);
30         }
31     }
32 }
33 
34 int lca(int x,int y)
35 {
36     if (d[x]<d[y])
37     {
38         swap(x,y);
39     }
40     int h=d[x]-d[y],k=0;
41     while (h)
42     {
43         if (h&1)
44         {
45             x=f[x][k];
46         }
47         h>>=1;
48         k++;
49     }
50     if (x==y)
51     {
52         return x;
53     }
54     for (int k=19; k>=0; k--)
55     {
56         if (f[x][k]!=f[y][k])
57         {
58             x=f[x][k];
59             y=f[y][k];
60         }
61     }
62     return f[x][0];
63 }
64 
65 int n,m,s;
66 int main()
67 {
68     scanf("%d%d%d",&n,&m,&s);
69     for (int i=1; i<n; i++)
70     {
71         scanf("%d%d",&x,&y);
72         add(x,y);
73         add(y,x);
74     }
75     dfs(s,0);
76     for (int i=1;i<=m;i++){
77         scanf("%d%d",&x,&y);
78         printf("%d\n",lca(x,y));
79     }
80 }
View Code 

LCT

  1 #include <iostream>
  2 #include <ctime>
  3 #include <cstdio>
  4 #include <cctype>
  5 namespace FastIO
  6 {
  7 char buf[1 << 21], buf2[1 << 21], a[20], *p1 = buf, *p2 = buf, hh = '\n';
  8 int p, p3 = -1;
  9 void read() {}
 10 void print() {}
 11 inline int getc()
 12 {
 13     return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
 14 }
 15 inline void flush()
 16 {
 17     fwrite(buf2, 1, p3 + 1, stdout), p3 = -1;
 18 }
 19 template <typename T, typename... T2>
 20 inline void read(T &x, T2 &... oth)
 21 {
 22     int f = 0;
 23     x = 0;
 24     char ch = getc();
 25     while (!isdigit(ch))
 26     {
 27         if (ch == '-')
 28             f = 1;
 29         ch = getc();
 30     }
 31     while (isdigit(ch))
 32     {
 33         x = x * 10 + ch - 48;
 34         ch = getc();
 35     }
 36     x = f ? -x : x;
 37     read(oth...);
 38 }
 39 template <typename T, typename... T2>
 40 inline void print(T x, T2... oth)
 41 {
 42     if (p3 > 1 << 20)
 43         flush();
 44     if (x < 0)
 45         buf2[++p3] = 45, x = -x;
 46     do
 47     {
 48         a[++p] = x % 10 + 48;
 49     } while (x /= 10);
 50     do
 51     {
 52         buf2[++p3] = a[p];
 53     } while (--p);
 54     buf2[++p3] = hh;
 55     print(oth...);
 56 }
 57 } // namespace FastIO
 58 #define read FastIO::read
 59 #define print FastIO::print
 60 //======================================
 61 const int maxn = 1e5+5;
 62 struct Node
 63 {
 64     int fa,ch[2],val,res;   //res是异或结果
 65     bool tag;               //翻转懒标记
 66 }spl[maxn];
 67 //因为被毒瘤数据卡得TLE一个点,所以全部换成了#define。都是字面意思
 68 #define ls(x) (spl[x].ch[0])
 69 #define rs(x) (spl[x].ch[1])
 70 #define fa(x) (spl[x].fa)
 71 #define ident(x,f) (rs(f)==x)       //和下面的connect都是Splay的辅助函数
 72 #define connect(x,f,s) spl[fa(x)=f].ch[s]=x
 73 #define update(x) spl[x].res=spl[ls(x)].res^spl[rs(x)].res^spl[x].val
 74 #define ntroot(x) (ls(fa(x))==x||rs(fa(x))==x)  //判断结点是否为Splay的根
 75 #define reverse(x) std::swap(ls(x),rs(x)),spl[x].tag^=1
 76 inline void pushdw(int x)           //懒标记下传
 77 {
 78     if(spl[x].tag)
 79     {
 80         if(ls(x)) reverse(ls(x));
 81         if(rs(x)) reverse(rs(x));
 82     }
 83     spl[x].tag=0;
 84 }
 85 void pushall(int x)                 //头递归,从上到下下传所有懒标记
 86 {
 87     if(ntroot(x)) pushall(fa(x));
 88     pushdw(x);
 89 }
 90 inline void rotate(int x)           //Splay基操
 91 {
 92     int f=fa(x),ff=fa(f),k=ident(x,f);
 93     connect(spl[x].ch[k^1],f,k);
 94     fa(x)=ff;
 95     if(ntroot(f)) spl[ff].ch[ident(f,ff)]=x;//※重要,不能忘记判断,关系到虚实边
 96     connect(f,x,k^1);
 97     update(f),update(x);
 98 }
 99 inline void splaying(int x)         //Splay基操,都是伸展到根结点
100 {
101     pushall(x);                     //要先把上面的懒标记全都下传
102     while(ntroot(x))
103     {
104         int f=fa(x),ff=fa(f);
105         if(ntroot(f)) ident(f,ff)^ident(x,f)?rotate(x):rotate(f);
106         rotate(x);
107     }
108 }
109 inline void access(int x)           //从x到原树根结点拉一条实链
110 {
111     for(int y=0;x;x=fa(y=x))        //y为上一个Splay的根
112     {
113         splaying(x);                //伸展到当前Splay的根
114         rs(x)=y;                    //右儿子连上上一个Splay的根
115         update(x);                  //别忘更新>﹏<
116     }
117 }
118 inline void mkroot(int x)           //给原树换根
119 {
120     access(x);                      //先拉实链,拉好后x一定在Splay的最右(深度最大)
121     splaying(x);                    //再伸展,伸展后x必定没有右儿子
122     reverse(x);                     //翻转拉出来这条实链,使深度顺序翻转
123 }
124 inline int findroot(int x)          //寻找结点在原树的根
125 {
126     access(x);                      //先拉实链
127     splaying(x);                    //再伸展
128     while(ls(x))                    //因为根结点必定深度最小,所以不停往左找就OK了
129     {
130         pushdw(x);                  //别忘了下传,第一个儿子是没问题的但是第二个往后……
131         x=ls(x);
132     }
133     splaying(x);                    //用来保证时间复杂度,防止卡链
134     return x;
135 }
136 inline void link(int x,int y)       //连边,不保证数据合法
137 {
138     mkroot(x);                      //换根
139     if(findroot(y)==x) return;      //如果y所在的树的根结点是x,那说明两者在一棵树上
140     fa(x)=y;
141 }
142 inline void cut(int x,int y)        //断边,不保证数据合法
143 {
144     mkroot(x);                      //换根
145     //? 如果y跟x不在一棵树上 or x和y之间不是紧紧挨着的,return
146     //! 注意这里findroot后由于保证复杂度的一句伸展,导致刚才被换成根的x成为了Splay的根结点
147     //* 又因为x在原树中是根结点,深度最小,所以在Splay中一定是x为根结点y为其右儿子
148     if(findroot(y)!=x||fa(y)!=x||ls(y)) return;
149     fa(y)=rs(x)=0;                  //双向断边
150     update(x);                      //别忘更新>﹏<
151 }
152 inline void split(int x,int y)      //把x--y的路径拆出来
153 {
154     mkroot(x);                      //换根
155     access(y);                      //拉实链
156     splaying(y);                    //伸展
157     //? 此时y必定没有右儿子且左儿子是一条到x的实链,所以访问y就可以作任何关于这条链的操作了
158 }
159 int main(int argc, char const *argv[])
160 {
161 #ifndef ONLINE_JUDGE
162     freopen("in.in", "r", stdin);
163     freopen("out.out", "w", stdout);
164 #endif
165     clock_t c1 = clock();
166     //======================================
167     int n,m;
168     read(n,m);
169     //? 刚开始的时候所有点之间都没连着
170     for(int i=1;i<=n;i++) read(spl[i].val);
171     while(m--)
172     {
173         int opt,x,y;
174         read(opt,x,y);
175         switch(opt)
176         {
177         case 0:
178             split(x,y);
179             print(spl[y].res);      //访问y就相当于访问这条链了
180             break;
181         case 1:
182             link(x,y);
183             break;
184         case 2:
185             cut(x,y);
186             break;
187         case 3:
188             splaying(x);            //注意要先伸展到根,否则会很麻烦
189             spl[x].val=y;
190             update(x);              //不更新也没啥问题,加不加都行
191             break;
192         }
193     }
194     //======================================
195     FastIO::flush();
196     std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
197     return 0;
198 }
View Code
  1 #include <iostream>
  2 #include <ctime>
  3 #include <cstdio>
  4 #include <cctype>
  5 namespace FastIO
  6 {
  7 char buf[1 << 21], buf2[1 << 21], a[20], *p1 = buf, *p2 = buf, hh = '\n';
  8 int p, p3 = -1;
  9 void read() {}
 10 void print() {}
 11 inline int getc()
 12 {
 13     return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
 14 }
 15 inline void flush()
 16 {
 17     fwrite(buf2, 1, p3 + 1, stdout), p3 = -1;
 18 }
 19 template <typename T, typename... T2>
 20 inline void read(T &x, T2 &... oth)
 21 {
 22     int f = 0;
 23     x = 0;
 24     char ch = getc();
 25     while (!isdigit(ch))
 26     {
 27         if (ch == '-')
 28             f = 1;
 29         ch = getc();
 30     }
 31     while (isdigit(ch))
 32     {
 33         x = x * 10 + ch - 48;
 34         ch = getc();
 35     }
 36     x = f ? -x : x;
 37     read(oth...);
 38 }
 39 template <typename T, typename... T2>
 40 inline void print(T x, T2... oth)
 41 {
 42     if (p3 > 1 << 20)
 43         flush();
 44     if (x < 0)
 45         buf2[++p3] = 45, x = -x;
 46     do
 47     {
 48         a[++p] = x % 10 + 48;
 49     } while (x /= 10);
 50     do
 51     {
 52         buf2[++p3] = a[p];
 53     } while (--p);
 54     buf2[++p3] = hh;
 55     print(oth...);
 56 }
 57 } // namespace FastIO
 58 #define read FastIO::read
 59 #define print FastIO::print
 60 //======================================
 61 const int maxn = 2e5+5;
 62 int n;
 63 struct Node
 64 {
 65     int l,r,val;
 66 }hjt[maxn*40*2];
 67 int cnt,rootfa[maxn],rootdep[maxn],tot;
 68 void build(int l,int r,int &now)
 69 {
 70     now = ++cnt;
 71     if(l==r)
 72     {
 73         hjt[now].val=++tot;
 74         return;
 75     }
 76     int m = (l+r)>>1;
 77     build(l,m,hjt[now].l);
 78     build(m+1,r,hjt[now].r);
 79 }
 80 void modify(int l,int r,int ver,int &now,int pos,int val)
 81 {
 82     hjt[now=++cnt]=hjt[ver];
 83     if(l==r)
 84     {
 85         hjt[now].val=val;
 86         return;
 87     }
 88     int m = (l+r)>>1;
 89     if(pos<=m) modify(l,m,hjt[ver].l,hjt[now].l,pos,val);
 90     else modify(m+1,r,hjt[ver].r,hjt[now].r,pos,val);
 91 }
 92 int query(int l,int r,int now,int pos)
 93 {
 94     if(l==r) return hjt[now].val;
 95     int m = (l+r)>>1;
 96     if(pos<=m) return query(l,m,hjt[now].l,pos);
 97     else return query(m+1,r,hjt[now].r,pos);
 98 }
 99 int find(int ver,int x)
100 {
101     int fx = query(1,n,rootfa[ver],x);
102     return fx==x?x:find(ver,fx);
103 }
104 void merge(int ver,int x,int y)
105 {
106     x = find(ver-1,x);          //ver-1
107     y = find(ver-1,y);
108     if(x==y)
109     {
110         rootfa[ver]=rootfa[ver-1];
111         rootdep[ver]=rootdep[ver-1];
112     }
113     else
114     {
115         int depx = query(1,n,rootdep[ver-1],x);
116         int depy = query(1,n,rootdep[ver-1],y);
117         if(depx<depy)
118         {
119             modify(1,n,rootfa[ver-1],rootfa[ver],x,y);
120             rootdep[ver]=rootdep[ver-1];
121         }
122         else if(depx>depy)
123         {
124             modify(1,n,rootfa[ver-1],rootfa[ver],y,x);
125             rootdep[ver]=rootdep[ver-1];
126         }
127         else
128         {
129             modify(1,n,rootfa[ver-1],rootfa[ver],x,y);
130             modify(1,n,rootdep[ver-1],rootdep[ver],y,depy+1);
131         }
132     }
133 }
134 int main(int argc, char const *argv[])
135 {
136 #ifndef ONLINE_JUDGE
137     freopen("in.in", "r", stdin);
138     freopen("out.out", "w", stdout);
139 #endif
140     clock_t c1 = clock();
141     //======================================
142     int m;
143     read(n,m);
144     build(1,n,rootfa[0]);
145     for(int ver=1;ver<=m;ver++)
146     {
147         int opt,x,y;
148         read(opt);
149         switch(opt)
150         {
151         case 1:
152             read(x,y);
153             merge(ver,x,y);
154             break;
155         case 2:
156             read(x);
157             rootfa[ver]=rootfa[x];
158             rootdep[ver]=rootdep[x];
159             break;
160         case 3:
161             read(x,y);
162             rootfa[ver]=rootfa[ver-1];
163             rootdep[ver]=rootdep[ver-1];
164             int fx = find(ver,x);
165             int fy = find(ver,y);
166             print(fx==fy?1:0);
167             break;
168         }
169     }
170     //======================================
171     FastIO::flush();
172     std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
173     return 0;
174 }
View Code
  1 #include <iostream>
  2 #include <ctime>
  3 #include <cstdio>
  4 #include <cctype>
  5 namespace FastIO
  6 {
  7 char buf[1 << 21], buf2[1 << 21], a[20], *p1 = buf, *p2 = buf, hh = '\n';
  8 int p, p3 = -1;
  9 void read() {}
 10 void print() {}
 11 inline int getc()
 12 {
 13     return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
 14 }
 15 inline void flush()
 16 {
 17     fwrite(buf2, 1, p3 + 1, stdout), p3 = -1;
 18 }
 19 template <typename T, typename... T2>
 20 inline void read(T &x, T2 &... oth)
 21 {
 22     int f = 0;
 23     x = 0;
 24     char ch = getc();
 25     while (!isdigit(ch))
 26     {
 27         if (ch == '-')
 28             f = 1;
 29         ch = getc();
 30     }
 31     while (isdigit(ch))
 32     {
 33         x = x * 10 + ch - 48;
 34         ch = getc();
 35     }
 36     x = f ? -x : x;
 37     read(oth...);
 38 }
 39 template <typename T, typename... T2>
 40 inline void print(T x, T2... oth)
 41 {
 42     if (p3 > 1 << 20)
 43         flush();
 44     if (x < 0)
 45         buf2[++p3] = 45, x = -x;
 46     do
 47     {
 48         a[++p] = x % 10 + 48;
 49     } while (x /= 10);
 50     do
 51     {
 52         buf2[++p3] = a[p];
 53     } while (--p);
 54     buf2[++p3] = hh;
 55     print(oth...);
 56 }
 57 } // namespace FastIO
 58 #define read FastIO::read
 59 #define print FastIO::print
 60 //======================================
 61 const int maxn = 1e6+5;
 62 int a[maxn];
 63 struct Node
 64 {
 65     int l,r,val;
 66 }hjt[maxn*40];
 67 int cnt,root[maxn];
 68 void build(int l,int r,int &now)
 69 {
 70     now=++cnt;
 71     if(l==r)
 72     {
 73         hjt[now].val=a[l];
 74         return;
 75     }
 76     int m = (l+r)>>1;
 77     build(l,m,hjt[now].l);
 78     build(m+1,r,hjt[now].r);
 79 }
 80 void modify(int l,int r,int ver,int &now,int &pos,int &num)
 81 {
 82     hjt[now=++cnt]=hjt[ver];
 83     if(l==r)
 84     {
 85         hjt[now].val=num;
 86         return;
 87     }
 88     int m = (l+r)>>1;
 89     if(pos<=m) modify(l,m,hjt[ver].l,hjt[now].l,pos,num);
 90     else modify(m+1,r,hjt[ver].r,hjt[now].r,pos,num);
 91 }
 92 int query(int l,int r,int now,int &pos)
 93 {
 94     if(l==r) return hjt[now].val;
 95     int m = (l+r)>>1;
 96     if(pos<=m) return query(l,m,hjt[now].l,pos);
 97     else return query(m+1,r,hjt[now].r,pos);
 98 }
 99 int main(int argc, char const *argv[])
100 {
101 #ifndef ONLINE_JUDGE
102     freopen("in.in", "r", stdin);
103     freopen("out.out", "w", stdout);
104 #endif
105     clock_t c1 = clock();
106     //======================================
107     int n,m,ver,opt,x,y;
108     read(n,m);
109     for(int i=1;i<=n;i++) read(a[i]);
110     build(1,n,root[0]);
111     for(int i=1;i<=m;i++)
112     {
113         read(ver,opt);
114         switch(opt)
115         {
116         case 1:
117             read(x,y);
118             modify(1,n,root[ver],root[i],x,y);
119             break;
120         case 2:
121             read(x);
122             print(query(1,n,root[ver],x));
123             root[i]=root[ver];
124             break;
125         }
126     }
127     //======================================
128     FastIO::flush();
129     std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
130     return 0;
131 }
View Code

 次小生成树

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 typedef long long ll;
  5 
  6 const int maxn=1e5+10;
  7 const ll inf=0x3f3f3f3f;
  8 
  9 int n,m,fa[maxn],val1,val2,dp[3][maxn][20],t,head[maxn],f[maxn][20],deep[maxn];
 10 ll ans,ans_max;
 11 struct edge1 {
 12     int v, next,w;
 13 }e[maxn*2];
 14 struct edge2 {
 15     int u, v, w, vis;
 16 
 17     bool operator<(const edge2 &b) const {
 18         return w < b.w;
 19     }
 20 }a[maxn*3];
 21 
 22 void add(int u,int v,int w) {
 23     t++;
 24     e[t].v = v;
 25     e[t].w = w;
 26     e[t].next = head[u];
 27     head[u] = t;
 28 }
 29 
 30 int fin(int x){
 31     return x==fa[x]?x:fa[x]=fin(fa[x]);
 32 }
 33 void Kruskal() {
 34     sort(a + 1, a + m + 1);
 35     for (int i = 1; i <= m; i++) {
 36         int u = fin(a[i].u);
 37         int v = fin(a[i].v);
 38         if (u == v) continue;
 39         fa[u] = v;
 40         a[i].vis = 1;
 41         ans += 1ll*a[i].w;
 42         add(a[i].u, a[i].v, a[i].w);
 43         add(a[i].v, a[i].u, a[i].w);
 44     }
 45 }
 46 
 47 void dfs(int u,int fa) {
 48 
 49     for (int i = 1; (1 << i) <= deep[u]; i++) {
 50         f[u][i] = f[f[u][i - 1]][i - 1];
 51 
 52         dp[0][u][i] = max(dp[0][u][i - 1], dp[0][f[u][i - 1]][i - 1]);
 53         if (dp[0][u][i - 1] != dp[0][f[u][i - 1]][i - 1]) {
 54             dp[1][u][i] = min(dp[0][u][i - 1], dp[0][f[u][i - 1]][i - 1]);
 55             dp[1][u][i] = max(dp[1][u][i], dp[1][u][i - 1]);
 56             dp[1][u][i] = max(dp[1][u][i], dp[1][f[u][i - 1]][i - 1]);
 57         }
 58         else
 59             dp[1][u][i] = max(dp[1][u][i - 1], dp[1][f[u][i - 1]][i - 1]);
 60     }
 61 
 62     for (int i = head[u]; i; i = e[i].next) {
 63         int v = e[i].v;
 64         if (v == fa) continue;
 65         f[v][0] = u;
 66         dp[0][v][0] = e[i].w;
 67         dp[1][v][0] = -inf;
 68         deep[v] = deep[u] + 1;
 69         dfs(v, u);
 70     }
 71 }
 72 
 73 void update2(int x) {
 74     if (x > val1) {
 75         val2 = val1;
 76         val1 = x;
 77     } else if (x > val2 && x != val1)
 78         val2 = x;
 79 }
 80 
 81 void update(int x,int i) {
 82     update2(dp[0][x][i]);
 83     update2(dp[1][x][i]);
 84 }
 85 
 86 void lca(int x,int y) {
 87     val1 = val2 = -inf;
 88     if (deep[x] < deep[y]) {
 89         swap(x, y);
 90     }
 91     int h = deep[x] - deep[y], k = 0;
 92     while (h) {
 93 
 94         if (h & 1) {
 95             update(x,k);
 96             x = f[x][k];
 97         }
 98         h >>= 1;
 99         k++;
100     }
101     if (x == y) return;
102     for (int k = 19; k >= 0; k--) {
103         if (f[x][k] != f[y][k]) {
104             update(x, k);
105             x = f[x][k];
106             update(y, k);
107             y = f[y][k];
108         }
109     }
110     update(x,0);
111     update(y,0);
112 }
113 
114 int main() {
115     scanf("%d%d", &n, &m);
116     for (int i=1;i<=n;i++){
117         fa[i]=i;
118     }
119     for (int i = 1; i <= m; i++) {
120         scanf("%d%d%d", &a[i].u, &a[i].v, &a[i].w);
121     }
122     Kruskal();
123     dfs(1, 0);
124     ans_max = 0x3f3f3f3f3f3f3f3f;
125     for (int i = 1; i <= m; i++) {
126         if (!a[i].vis) {
127             lca(a[i].u, a[i].v);
128             if (val1 != a[i].w)
129                 ans_max = min(ans_max, ans - val1 + a[i].w);
130             else ans_max = min(ans_max, ans - val2 + a[i].w);
131         }
132     }
133     printf("%lld\n", ans_max);
134 }
View Code

 割点模板

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int maxn=20010;
 5 int cnt[maxn],t,tim,sta[maxn],dfn[maxn],low[maxn],top,head[maxn],flag,root;
 6 struct edge{
 7     int to,next;
 8 }e[maxn*5];
 9 void add(int u,int v){
10     t++;
11     e[t].to=v;
12     e[t].next=head[u];
13     head[u]=t;
14 }
15 
16 void tarjan(int u) {
17     low[u] = dfn[u] = ++tim;
18     int flag=0;
19     for (int i = head[u]; i; i = e[i].next) {
20         int v = e[i].to;
21         if (!dfn[v]) {//不曾访问过,也就是没有标记,可以认为是儿子节点了
22             tarjan(v);//访问儿子节点y,并且设置边为当前边
23             low[u] = min(low[u], low[v]);//看看能不能更新,也就是定义中的,subtree(x)中的节点最小值为low[x]
24             //subtree(x)表示搜索树中以x节点为根的子树节点集合
25             if (low[v] >= dfn[u]) {//这就是割点的判定
26                 flag++;//割点数量++
27                 if (u != root || flag > 1) //不能是根节点,或者说是根节点,但是有至少两个子树节点是割点
28                     cnt[u] = 1;
29             }
30         } else
31             low[u] = min(low[u], dfn[v]);//第二类定义,也就是通过1跳不在搜索树上的边,能够抵达subtree(x)的节点
32     }
33 }
34 int main() {
35     int n,m, ans=0;
36     scanf("%d%d", &n, &m);
37     for (int i = 1, u, v; i <= m; i++) {
38         scanf("%d%d", &u, &v);
39         add(u, v);
40         add(v, u);
41     }
42     for (int i = 1; i <= n; i++) {
43         if (!dfn[i]) {        //一个无向图,可能由多个搜索树构成
44             root = i;
45             tarjan(i);
46         }
47     }
48     for (int i = 1; i <= n; i++) {//统计割点个数
49         if (cnt[i]) ans++;
50     }
51     int num=0;
52     printf("%d\n", ans);
53     for (int i = 1; i <= n; i++) {
54         if (cnt[i]) {
55             num++;
56             printf("%d", i);
57             if (num < ans) printf(" "); else printf("\n");
58         }//顺序遍历,康康哪些点是割点
59     }
60     return 0;
61 }
View Code

割边模板

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int maxn=100010;
 5 int cnt[maxn],t,tim,bridge[maxn*6],dfn[maxn],low[maxn],top,head[maxn],flag,root;
 6 struct edge{
 7     int to,next;
 8 }e[maxn*6];
 9 void add(int u,int v){
10     t++;
11     e[t].to=v;
12     e[t].next=head[u];
13     head[u]=t;
14 }
15 
16 void tarjan(int u,int edge) {
17     low[u] = dfn[u] = ++tim;
18     for (int i = head[u]; i; i = e[i].next) {
19         int v = e[i].to;
20         if (!dfn[v]) {//不曾访问过,也就是没有标记,可以认为是儿子节点了
21             tarjan(v, i);//访问儿子节点y,并且设置边为当前边
22             low[u] = min(low[u], low[v]);//看看能不能更新,也就是定义中的,subtree(x)中的节点最小值为low[x]
23             //subtree(x)表示搜索树中以x节点为根的子树节点集合
24             if (low[v] > dfn[u]) //这就是割点的判定
25                 bridge[i] = bridge[i ^ 1] = 1;//重边也是桥
26         } else if (i != (edge ^ 1))
27             low[u] = min(low[u], dfn[v]);//第二类定义,也就是通过1跳不在搜索树上的边,能够抵达subtree(x)的节点
28     }
29 }
30 int main() {
31     t = 1;
32     int n, m, ans = 0;
33     scanf("%d%d", &n, &m);
34     for (int i = 1, u, v; i <= m; i++) {
35         scanf("%d%d", &u, &v);
36         add(u, v);
37         add(v, u);
38     }
39     for (int i = 1; i <= n; i++) {
40         if (!dfn[i])       //一个无向图,可能由多个搜索树构成
41             tarjan(i, 0);
42     }
43     int num=0;
44     for (int i = 2; i <= t; i+=2) {
45         if (bridge[i])
46             num++;
47     }
48     printf("%d\n",m-num);
49 }
View Code

 Tarjan

 1 void tarjan(int u) {
 2     low[u] = dfn[u] = ++index;
 3     stack[top++] = u;
 4     for (int i = head[u]; i; i = e[i].next) {
 5         int v = e[i].to;
 6         if (!dfn[v]) {
 7             tarjan(v);
 8             low[u] = min(low[u], low[v]);
 9         } else {
10             if (!blong[v]) {
11                 low[u] = min(low[u], dfn[v]);
12             }
13         }
14     }
15     if (dfn[u] == low[u]) {
16         scc++;
17         for (;;) {
18             v = stack[--top];
19             belong[v] = scc;
20             if (v == u) break;
21         }
22     }
23 }
View Code

 

动态查询区间第k大

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 const int maxn=250000;
  6 const int M=250000*400;
  7 int n,q,m,tot;
  8 int a[maxn],t[maxn];
  9 int T[maxn],lson[M],rson[M],c[M];
 10 int S[maxn];
 11 struct Query{
 12     int kind;
 13     int l,r,k;
 14 }query[100100];
 15 void init_hash(int k){
 16     sort(t,t+k);
 17     m=unique(t,t+k)-t;
 18 }
 19 int hash1(int x){
 20     return lower_bound(t,t+m,x)-t;
 21 }
 22 
 23 int build(int l,int r) {
 24     int root = tot++;
 25     c[root] = 0;
 26     if (l != r) {
 27         int mid = (l + r) >> 1;
 28         lson[root] = build(l, mid);
 29         rson[root] = build(mid + 1, r);
 30     }
 31     return root;
 32 }
 33 
 34 int insert(int root,int pos,int val) {
 35     int newroot = tot++, tmp = newroot;
 36     int l = 0, r = m - 1;
 37     c[newroot] = c[root] + val;
 38     while (l < r) {
 39         int mid = (l + r) >> 1;
 40         if (pos <= mid) {
 41             lson[newroot] = tot++;
 42             rson[newroot] = rson[root];
 43             newroot = lson[newroot];
 44             root = lson[root];
 45             r = mid;
 46         } else {
 47             rson[newroot] = tot++;
 48             lson[newroot] = lson[root];
 49             newroot = rson[newroot];
 50             root = rson[root];
 51             l = mid + 1;
 52         }
 53         c[newroot] = c[root] + val;
 54     }
 55     return tmp;
 56 }
 57 
 58 int lowbit(int x) {
 59     return x & -x;
 60 }
 61 
 62 int use[maxn];
 63 
 64 int sum(int x) {
 65     int ret = 0;
 66     while (x) {
 67         ret += c[lson[use[x]]];
 68         x -= lowbit(x);
 69     }
 70     return ret;
 71 }
 72 
 73 int Query(int left,int right,int k) {
 74     int left_root = T[left - 1];
 75     int right_root = T[right];
 76     int l = 0, r = m - 1;
 77     for (int i = left - 1; i; i -= lowbit(i)) use[i] = S[i];
 78     for (int i = right; i; i -= lowbit(i)) use[i] = S[i];
 79     while (l < r) {
 80         int mid = (l + r) >> 1;
 81         int tmp = sum(right) - sum(left - 1) + c[lson[right_root]] - c[lson[left_root]];
 82         if (tmp >= k) {
 83             r = mid;
 84             for (int i = left - 1; i; i -= lowbit(i)) use[i] = lson[use[i]];
 85             for (int i = right; i; i -= lowbit(i)) use[i] = lson[use[i]];
 86             left_root = lson[left_root];
 87             right_root = lson[right_root];
 88         } else {
 89             l = mid + 1;
 90             k -= tmp;
 91             for (int i = left - 1; i; i -= lowbit(i)) use[i] = rson[use[i]];
 92             for (int i = right; i; i -= lowbit(i)) use[i] = rson[use[i]];
 93             left_root = rson[left_root];
 94             right_root = rson[right_root];
 95         }
 96     }
 97     return l;
 98 }
 99 
100 void Modify(int x,int p,int d) {
101     while (x <= n) {
102         S[x] = insert(S[x], p, d);
103         x += lowbit(x);
104     }
105 }
106 
107 int main() {
108     scanf("%d%d", &n, &q);
109     for (int i = 1; i <= n; i++) {
110         scanf("%d", &a[i]);
111         t[m++] = a[i];
112     }
113     char op[10];
114     for (int i = 0; i < q; i++) {
115         scanf("%s", op);
116         if (op[0] == 'Q') {
117             query[i].kind = 0;
118             scanf("%d%d%d", &query[i].l, &query[i].r, &query[i].k);
119         } else {
120             query[i].kind = 1;
121             scanf("%d%d", &query[i].l, &query[i].r);
122             t[m++] = query[i].r;
123         }
124     }
125     init_hash(m);
126     T[0] = build(0, m - 1);
127     for (int i = 1; i <= n; i++) {
128         T[i] = insert(T[i - 1], hash1(a[i]), 1);
129     }
130     for (int i = 1; i <= n; i++) {
131         S[i] = T[0];
132     }
133     for (int i = 0; i < q; i++) {
134         if (query[i].kind == 0) {
135             printf("%d\n", t[Query(query[i].l, query[i].r, query[i].k)]);
136         } else {
137             Modify(query[i].l, hash1(a[query[i].l]), -1);
138             Modify(query[i].l, hash1(query[i].r), 1);
139             a[query[i].l] = query[i].r;
140         }
141     }
142     return 0;
143 }
View Code

 

 

 
 

 

  

 

 

  

posted @ 2019-08-26 11:55  Snow_in_winer  阅读(206)  评论(0编辑  收藏  举报