トピックポータル(内部タイトル146)
入力形式
データは$ geography.in $から読み取ります。
最初の2つの行番号$ N、N-発現$、$ m個の点は$、$ M $時間。各3つの数字$ M $行の行、いずれかのエッジにエッジを追加、削除無向なし$ 1 \ uが\ V $、いずれか$ 2 \ uは、それぞれ\ V $、、。
出力フォーマット
$ geography.out $への出力の答え。
合計$は$行をM、各列は、通信ブロックサイズ製品$ \ MOD十億七$の数を表します。
サンプル
サンプル入力:
5 6
1 1 3
1 2 3
1 2
1 4 5
1 3 4
2 3 4
出力例:
2
3
3
6
5
6
データ範囲とヒント
サンプルは説明しました:
上記各図の動作タイミングです。生成物は、次のとおり
$$ 2 \タイムズ1 \タイムズ1 \ = 2,3 1回\タイムズ1 \ = 3,3 1回\タイムズ1 \時間= 3,3 1 \ 2 = 6,5,3回\タイムズ。。。。。。。 2 = 6 $$
データ範囲:
$ subtask1:30pts、nは\ leqslant 1,000メートル\ leqslant 2,000 $。
$ subtask2:20pts $、削除操作を満たしていません。
$ subtask3:50pts、N、M \ leqslant $ 100,000。リングからの重い側は、存在しない側を削除しないことがないように。
問題の解決策
これは、テンプレート質問のようです。
具体的なアイデアオフライン発行することで、セグメントツリーを構築するための時間は、ツリーラインセグメントは分割統治するとき、ときにすることができ、基礎となる統計に対する答えを互いに素-セットを追加しながら、再帰が続行されます。
需要注意的是还要支持回退,在递归下去的时候记录一下当前修改了哪些点的$father$或者权值,返回的时候直接改回来即可。
时间复杂度:$\Theta(\omega\times n\log n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
const int mod=1000000007;
struct rec{int nxt,to;}e[200001];
int head[100001],cnt;
map<pair<int,int>,int>mp;
int n,m;
int f[100001],sz[100001],question[100001];
pair<int,int>wzc[100001];
vector<int>tr[400001];
vector<pair<pair<int,int>,pair<int,int>>>vec[400001];
long long qpow(long long x,long long y)
{
long long res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;y>>=1;
}
return res;
}
int find(int x){return x==f[x]?x:find(f[x]);}
void change(int x,int l,int r,int L,int R,int w)
{
if(r<L||R<l)return;
if(L<=l&&r<=R){tr[x].push_back(w);return;}
int mid=(l+r)>>1;
change(L(x),l,mid,L,R,w);
change(R(x),mid+1,r,L,R,w);
}
void ask(int x,int l,int r,int k)
{
for(int i=0;i<tr[x].size();i++)
{
int fx=find(wzc[tr[x][i]].first);
int fy=find(wzc[tr[x][i]].second);
if(fx==fy)continue;
if(sz[fx]<sz[fy])fx^=fy^=fx^=fy;
vec[x].push_back(make_pair(make_pair(fx,sz[fx]),make_pair(fy,f[fy])));
k=1LL*k*qpow(sz[fx],mod-2)%mod*qpow(sz[fy],mod-2)%mod;
f[fy]=fx;
sz[fx]+=sz[fy];
k=1LL*k*sz[fx]%mod;
}
if(l==r)printf("%d\n",k);
else
{
int mid=(l+r)>>1;
ask(L(x),l,mid,k);
ask(R(x),mid+1,r,k);
}
for(int i=vec[x].size()-1;~i;i--)
{
f[vec[x][i].second.first]=vec[x][i].second.second;
sz[vec[x][i].first.first]=vec[x][i].first.second;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){f[i]=i;sz[i]=1;}
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d%d",&x,&x,&y);
if(x>y)x^=y^=x^=y;
int now=mp[make_pair(x,y)];
if(!now){mp[make_pair(x,y)]=++cnt;question[cnt]=i;wzc[cnt]=make_pair(x,y);}
else
{
if(question[now]){change(1,1,m,question[now],i-1,now);question[now]=0;}
else question[now]=i;
}
}
for(int i=1;i<=cnt;i++)if(question[i])change(1,1,m,question[i],m,i);
ask(1,1,m,1);
return 0;
}
rp++