이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#define LOCAL 1
#include <bits/stdc++.h>
using namespace std;
using i64=long long;
#define all(x) x.begin(),x.end()
#define pb push_back
#define UNSET -1
const int N = 50'000;
const int SQRT=230;
namespace dsu_roll_back
{
static int t[N],sz[N];
static int sk[N],sk_size;
void roll_back()
{
while(sk_size>0)
{
sz[t[sk[sk_size-1]]]-=sz[sk[sk_size-1]];
t[sk[sk_size-1]]=sk[sk_size-1];
sk_size--;
}
}
int root(int x)
{
if(t[x]!=x)
{
return root(t[x]);
}
return x;
}
void unite(int x,int y,bool roll)
{
x=root(x);
y=root(y);
if(sz[x]<sz[y])
{
swap(x,y);
}
if(x==y)
{
return;
}
t[y]=x;
sz[x]+=sz[y];
if(roll)
{
sk[sk_size++]=y;
}
}
void init(int n)
{
fill(sz,sz+n,1);
iota(t,t+n , 0);
sk_size=0;
}
int size(int x)
{
return sz[root(x)];
}
}
//do not edge kids
struct edge
{
int x,y,weight;
bool operator ==(const edge& b)const
{
return x==b.x && y==b.y && weight==b.weight;
}
};
struct query
{
int tip,poz,weight,rez;
};
static int n,m,q;
static vector<edge>edges;
static vector<query>querys;
static set<pair<int,int>>mp;
int old[N];
void solve_batch(const int l,const int r)
{
vector<bool>appears(m,false);
for(int i=l;i<r;i++)
{
if(querys[i].tip==1)
{
appears[querys[i].poz]=true;
}
}
vector<int>good;
vector<int>bad;
good.reserve(n);
bad.reserve(r-l+1);
for(auto &c:mp)
{
if(!appears[c.second])
{
good.pb(c.second);
}
else
{
bad.pb(c.second);
}
}
for(auto &c:bad)
{
mp.erase({-edges[c].weight , c});
}
vector<int>ord_querys(r-l,0);
iota(all(ord_querys) , l);
sort(all(ord_querys) , [&](int x,int y){
if(querys[x].weight==querys[y].weight)
{
return querys[x].tip<querys[y].tip;
}
return querys[x].weight>querys[y].weight;
});
vector<int>::iterator it_good=good.begin();
vector<int>::iterator it_ord_querys=ord_querys.begin();
dsu_roll_back::init(n);
for(;it_ord_querys!=ord_querys.end();it_ord_querys++)
{
if(querys[*it_ord_querys].tip==1)
{
continue;
}
for(;it_good!=good.end() && edges[*it_good].weight>=querys[*it_ord_querys].weight;it_good++)
{
dsu_roll_back::unite(edges[*it_good].x , edges[*it_good].y ,false);
}
for(int i=l;i<*it_ord_querys;i++)
{
if(querys[i].tip==1)
{
old[i-l]=edges[querys[i].poz].weight;
edges[querys[i].poz].weight=querys[i].weight;
}
}
for(auto &c:bad)
{
if(edges[c].weight>=querys[*it_ord_querys].weight)
{
dsu_roll_back::unite(edges[c].x , edges[c].y , true);
}
}
querys[*it_ord_querys].rez=dsu_roll_back::size(querys[*it_ord_querys].poz);
for(int i=*it_ord_querys-1;i>=l;i--)
{
if(querys[i].tip==1)
{
edges[querys[i].poz].weight=old[i-l];
}
}
dsu_roll_back::roll_back();
}
for(int i=l;i<r;i++)
{
if(querys[i].tip==1)
{
edges[querys[i].poz].weight=querys[i].weight;
}
}
for(auto &c:bad)
{
mp.insert({-edges[c].weight , c});
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m;
edges.resize(m);
for(int i=0;i<m;i++)
{
int x,y,z;
cin>>x>>y>>z;
x--;
y--;
mp.insert({-z , i});
edges[i]={x,y,z};
}
cin>>q;
querys.resize(q);
for(int i=0;i<q;i++)
{
cin>>querys[i].tip>>querys[i].poz>>querys[i].weight;
querys[i].poz--;
}
for(int i=0;i<q;i+=SQRT)
{
solve_batch(i,min(i+SQRT,q));
}
for(int i=0;i<q;i++)
{
if(querys[i].tip==2)
{
cout<<querys[i].rez<<'\n';
}
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |