日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

BZOJ3514:GERALD07加强版(LCT,主席树)

發布時間:2025/4/16 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ3514:GERALD07加强版(LCT,主席树) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

N個點M條邊的無向圖,詢問保留圖中編號在[l,r]的邊的時候圖中的聯通塊個數。

Input

第一行四個整數N、M、K、type,代表點數、邊數、詢問數以及詢問是否加密。
接下來M行,代表圖中的每條邊。
接下來K行,每行兩個整數L、R代表一組詢問。對于type=0的測試點,讀入的L和R即為詢問的L、R;對于type=1的測試點,每組詢問的L、R應為L xor lastans和R xor lastans。

Output

?K行每行一個整數代表該組詢問的聯通塊個數。

Sample Input

3 5 4 0
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2

Sample Output

2
1
3
1

HINT

對于100%的數據,1≤N、M、K≤200,000。

Solution

$namespace$真是個好東西QAQ

每次往里加邊,如果構成環的話就把最早的那條邊刪掉,這個可以用$LCT$隨便做。

定義一個數組$Early[i]$,表示加第$i$條邊的時候,會把哪條邊刪掉。

特殊的,如果不刪邊,$Early[i]=0$。如果第$i$條邊是自環,$Early[i]=i$。

然后對$Early$數組建主席樹,每次詢問的答案就是$[l,r]$區間內小于等于$l-1$的數個個數。

正確性……如果一條邊$i$的$Early[i]$在$l$后面的話,那么加入$i$的時候,因為會產生環所以不會對連通塊情況產生影響。否則如果$Early[i]$在$l$的前面的話,加入$i$就會對連通塊情況產生影響……

大體就是這樣子具體我也不會

Code

1 #include<iostream> 2 #include<cstdio> 3 #define N (400009) 4 using namespace std; 5 6 int n,m,k,opt,Early[N],x[N],y[N]; 7 8 namespace LCT 9 { 10 int Father[N],Son[N][2],Val[N],Min[N],Rev[N]; 11 12 int Get(int x) 13 { 14 return Son[Father[x]][1]==x; 15 } 16 int Is_root(int x) 17 { 18 return Son[Father[x]][0]!=x && Son[Father[x]][1]!=x; 19 } 20 void Pushup(int x) 21 { 22 Min[x]=x; 23 int ls=Son[x][0],rs=Son[x][1]; 24 if (Val[Min[ls]]<Val[Min[x]]) Min[x]=Min[ls]; 25 if (Val[Min[rs]]<Val[Min[x]]) Min[x]=Min[rs]; 26 } 27 void Pushdown(int x) 28 { 29 if (Rev[x]) 30 { 31 Rev[Son[x][0]]^=1; 32 Rev[Son[x][1]]^=1; 33 swap(Son[x][0],Son[x][1]); 34 Rev[x]=0; 35 } 36 } 37 void Rotate(int x) 38 { 39 int wh=Get(x); 40 int fa=Father[x],fafa=Father[fa]; 41 if (!Is_root(fa)) Son[fafa][Son[fafa][1]==fa]=x; 42 Father[fa]=x; Son[fa][wh]=Son[x][wh^1]; 43 if (Son[fa][wh]) Father[Son[fa][wh]]=fa; 44 Father[x]=fafa; Son[x][wh^1]=fa; 45 Pushup(fa); Pushup(x); 46 } 47 void Push(int x) 48 { 49 if (!Is_root(x)) Push(Father[x]); 50 Pushdown(x); 51 } 52 void Splay(int x) 53 { 54 Push(x); 55 for (int fa; !Is_root(x); Rotate(x)) 56 if (!Is_root(fa=Father[x])) 57 Rotate(Get(fa)==Get(x)?fa:x); 58 } 59 void Access(int x) 60 { 61 for (int y=0; x; y=x,x=Father[x]) 62 Splay(x), Son[x][1]=y, Pushup(x); 63 } 64 void Make_root(int x) 65 { 66 Access(x); Splay(x); Rev[x]^=1; 67 } 68 int Find_root(int x) 69 { 70 Access(x); Splay(x); 71 while (Son[x][0]) x=Son[x][0]; 72 return x; 73 } 74 void Link(int x,int y) 75 { 76 Make_root(x); Father[x]=y; 77 } 78 void Cut(int x,int y) 79 { 80 Make_root(x); Access(y); Splay(y); 81 Son[y][0]=Father[x]=0; Pushup(y); 82 } 83 int Query(int x,int y) 84 { 85 Make_root(x); Access(y); Splay(y); 86 return Min[y]; 87 } 88 void Build_Early() 89 { 90 for (int i=1; i<=m; ++i) Val[n+i]=i; 91 for (int i=0; i<=n; ++i) Val[i]=2e8,Min[i]=i; 92 for (int i=1; i<=m; ++i) 93 { 94 scanf("%d%d",&x[i],&y[i]); 95 if (x[i]==y[i]) {Early[i]=i; continue;} 96 if (Find_root(x[i])!=Find_root(y[i])) 97 Link(x[i],i+n), Link(y[i],i+n); 98 else 99 { 100 int p=Query(x[i],y[i]); 101 Early[i]=p-n; 102 Cut(x[p-n],p); Cut(y[p-n],p); 103 Link(x[i],i+n); Link(y[i],i+n); 104 } 105 } 106 } 107 } 108 109 namespace Sgt 110 { 111 struct Sgt{int ls,rs,val;}Segt[N*40]; 112 int sgt_num,Root[N]; 113 114 int Update(int pre,int l,int r,int x) 115 { 116 int now=++sgt_num; 117 Segt[now]=Segt[pre]; 118 Segt[now].val++; 119 if (l==r) return now; 120 int mid=(l+r)>>1; 121 if (x<=mid) Segt[now].ls=Update(Segt[now].ls,l,mid,x); 122 else Segt[now].rs=Update(Segt[now].rs,mid+1,r,x); 123 return now; 124 } 125 int Query(int u,int v,int l,int r,int l1,int r1) 126 { 127 if (l>r1 || r<l1) return 0; 128 if (l1<=l && r<=r1) return Segt[v].val-Segt[u].val; 129 int mid=(l+r)>>1; 130 return Query(Segt[u].ls,Segt[v].ls,l,mid,l1,r1)+Query(Segt[u].rs,Segt[v].rs,mid+1,r,l1,r1); 131 } 132 void Solve() 133 { 134 for (int i=1; i<=m; ++i) 135 Root[i]=Update(Root[i-1],0,2e5,Early[i]); 136 int ans=0,l,r; 137 for (int i=1; i<=k; ++i) 138 { 139 scanf("%d%d",&l,&r); 140 if (opt) l^=ans, r^=ans; 141 ans=n-Query(Root[l-1],Root[r],0,2e5,0,l-1); 142 printf("%d\n",ans); 143 } 144 } 145 } 146 147 int main() 148 { 149 scanf("%d%d%d%d",&n,&m,&k,&opt); 150 LCT::Build_Early(); 151 Sgt::Solve(); 152 }

轉載于:https://www.cnblogs.com/refun/p/10088908.html

總結

以上是生活随笔為你收集整理的BZOJ3514:GERALD07加强版(LCT,主席树)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。