zoukankan      html  css  js  c++  java
  • 洛谷 P4219 [BJOI2014]大融合

    查询,就相当于先删去这条边,然后查询边的两个端点所在连通块大小,乘起来得到答案,然后再把边加回去

    可以用线段树分治做

      1 #pragma GCC optimize("Ofast")
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<vector>
      6 #include<map>
      7 using namespace std;
      8 #define fi first
      9 #define se second
     10 #define mp make_pair
     11 #define pb push_back
     12 typedef long long ll;
     13 typedef unsigned long long ull;
     14 typedef pair<int,int> pi;
     15 #define N 100100
     16 struct Q
     17 {
     18     int type,x,y,l,r,num;
     19 }q[N*3];
     20 ll ans[N];
     21 int nq,n,qq,tm,an;
     22 char ss[10];
     23 int fa[N],sz[N],dp[N];
     24 map<pi,int> ma;
     25 int find(int x)
     26 {
     27     for(;x!=fa[x];x=fa[x]);
     28     return x;
     29 }
     30 int bx[N*17],bfa[N*17],bsz[N*17],bdp[N*17],mem;
     31 void unionn(int x,int y)
     32 {
     33     x=find(x),y=find(y);
     34     ++mem;bx[mem]=x;bfa[mem]=fa[x];bsz[mem]=sz[x];bdp[mem]=dp[x];
     35     ++mem;bx[mem]=y;bfa[mem]=fa[y];bsz[mem]=sz[y];bdp[mem]=dp[y];
     36     if(dp[x]<dp[y])    {fa[x]=y;sz[y]+=sz[x];}
     37     else
     38     {
     39         fa[y]=x;sz[x]+=sz[y];
     40         if(dp[x]==dp[y])    dp[x]++;
     41     }
     42 }
     43 void backn(int nn)
     44 {
     45     for(int i=1;i<=nn;i++)
     46     {
     47         fa[bx[mem]]=bfa[mem];sz[bx[mem]]=bsz[mem];dp[bx[mem]]=bdp[mem];--mem;
     48         fa[bx[mem]]=bfa[mem];sz[bx[mem]]=bsz[mem];dp[bx[mem]]=bdp[mem];--mem;
     49     }
     50 }
     51 void solve(int pl,int pr,int l,int r)//[l,r]为线段树上区间
     52 {
     53     if(pl>pr)    return;
     54     int i,nn=0;
     55     if(l==r)
     56     {
     57         for(i=pl;i<=pr;i++)
     58             if(q[i].type==0)
     59                 unionn(q[i].x,q[i].y),++nn;
     60         for(i=pl;i<=pr;i++)
     61             if(q[i].type==1)
     62                 ans[q[i].num]=ll(sz[find(q[i].x)])*sz[find(q[i].y)];
     63         backn(nn);
     64         return;
     65     }
     66     int mid=l+((r-l)>>1),p=pl-1;
     67     for(i=pl;i<=pr;i++)
     68     {
     69         if(q[i].l<=l&&r<=q[i].r)    unionn(q[i].x,q[i].y),++nn;
     70         else    if(q[i].l<=mid)    swap(q[++p],q[i]);
     71     }
     72     solve(pl,p,l,mid);p=pl-1;
     73     for(i=pl;i<=pr;i++)
     74     {
     75         if((q[i].l>l||r>q[i].r)&&mid<q[i].r)    swap(q[++p],q[i]);
     76     }
     77     solve(pl,p,mid+1,r);
     78     backn(nn);
     79 }
     80 int main()
     81 {
     82     int i,x,y;
     83     scanf("%d%d",&n,&qq);
     84     for(i=1;i<=qq;i++)
     85     {
     86         scanf("%s%d%d",ss,&x,&y);
     87         if(x>y)    swap(x,y);
     88         if(ss[0]=='A')
     89         {
     90             ma[mp(x,y)]=++tm;
     91         }
     92         else
     93         {
     94             q[++nq]=(Q){0,x,y,ma[mp(x,y)],++tm,0};
     95             ++tm;q[++nq]=(Q){1,x,y,tm,tm,++an};
     96             ma[mp(x,y)]=++tm;
     97         }
     98     }
     99     for(auto xx:ma)    q[++nq]=(Q){0,xx.fi.fi,xx.fi.se,xx.se,tm,0};
    100     for(i=1;i<=n;i++)    fa[i]=i,sz[i]=1;
    101     solve(1,nq,1,tm);
    102     for(i=1;i<=an;i++)    printf("%lld
    ",ans[i]);
    103     return 0;
    104 }
  • 相关阅读:
    简单小过一个crc
    BUUCTF-RE-babymips
    为IDA插件findcrypt添加更多规则
    2020网鼎杯第一场青龙组re部分wp
    HexionCTF2020 部分wp
    TGhack2020 re&misc
    java反射总结
    BUUCTF-RE-CrackMe
    青年大学习直接出图片的软件出了bug,用frida干他
    小玩具Teensy
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9287288.html
Copyright © 2011-2022 走看看