• 模板


      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
    ", 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
    ", 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
    ",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
    ",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 = '
    ';
      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 = '
    ';
      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 = '
    ';
      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
    ", 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
    ", 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("
    ");
    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
    ",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
    ", 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

     

     
     

      

     

      

  • 相关阅读:
    什么是透视图?
    Eclipse 视图
    Eclipse 菜单
    Eclipse 窗口说明
    Eclipse 修改字符集
    Eclipse 安装(Oxygen版本)
    Eclipse 教程
    jQuery 教程
    就表单验证说用户体验
    需要配置执行path?no
  • 原文地址:https://www.cnblogs.com/Accpted/p/11411713.html
Copyright © 2020-2023  润新知