Submission #493918

#TimeUsernameProblemLanguageResultExecution timeMemory
493918cadmiumskyBridges (APIO19_bridges)C++14
0 / 100
3071 ms10364 KiB
#include <iostream> #include <tuple> #include <set> #include <unordered_set> #include <algorithm> #include <stack> #include <vector> #include <cmath> using namespace std; #pragma GCC optimize ("Ofast") #pragma GCC target ("avx,avx2") const int mmax = 100005; const int nmax = 50005; const int qmax = 100005; int n, m; #define x first #define y second namespace DSU { stack< pair<int,int> >undostack; int dsu[nmax]; int area[nmax]; void init() { for(int i = 0; i < n; i++) { dsu[i]=i; area[i]=1; } while(!undostack.empty()) undostack.pop(); } int father(int x) { return (dsu[x]==x ? x : father(dsu[x])); } void unite(int x , int y) { x = father(x); y = father(y); if(x == y) return; if(area[x] > area[y]) { swap(x, y); } dsu[y] = x; area[x] += area[y]; undostack.push({x, y}); } int gettime() { return undostack.size(); } void popundo() { int x, y; tie(x,y) = undostack.top(); undostack.pop(); dsu[y] = y; area[x] -= area[y]; return; } void rollback(int x) { while(undostack.size() > x) popundo(); } int query(int x) { return area[father(x)]; } }; int weight[mmax]; int prevweight[mmax]; pair<int, int> edge[mmax]; int rez[qmax]; struct query { int type, x, w, ind; bool operator < (const query& camsus) const { return w<camsus.w || (w==camsus.w && (type%2>camsus.type%2 || (type%2==camsus.type%2 && tuple<int,int,int,int>{type, x, w, ind} < tuple<int,int,int,int>{camsus.type, camsus.x, camsus.w, camsus.ind} ))); } bool operator == (const query& camsus) const { return tuple<int,int,int,int>{type, x, w, ind} == tuple<int,int,int,int>{camsus.type, camsus.x, camsus.w, camsus.ind}; } }initq[qmax]; unordered_set< int > used; vector< query > inupd,qs,here; static vector<query> merge(vector<query> a, vector<query> b) { vector<query> temp; while(a.size() && b.size()) { if(b[0]<a[0]) swap(a,b); temp.push_back(a[0]); a.erase(a.begin()); } copy(b.begin(),b.end(),back_inserter(temp)); return temp; } static void solve(int l, int r) { DSU::rollback(0); if(used.size()!=0) used.erase(used.begin(),used.end()); if(here.size()) here.erase(here.begin(),here.end()); if(inupd.size()) inupd.erase(inupd.begin(),inupd.end()); for(int i = l; i <= r; i++) { if(initq[i].type == 1) { used.insert(initq[i].x); inupd.push_back(initq[i]); } else { here.push_back(initq[i]); } } sort(inupd.begin(),inupd.end()); sort(here.begin(),here.end()); int ptr=0; for(int i = 0; i < qs.size(); i++) { if(used.count(qs[i].x)) qs.erase(qs.begin()+i),i--; } //for(auto x:qs) //cout << "remain" <<x.type <<' '<< x.x << ' '<< x.w <<'\n'; qs=merge(qs,here); //cout << "====="; //for(auto x:qs) //cout << "remain" <<x.type <<' '<< x.x << ' '<< x.w <<'\n'; for(auto x:qs) { if(x.type == 3) { if(used.count(x.x)==0) DSU::unite(edge[x.x].x, edge[x.x].y); //cout << '+' << edge[x.x].x+1 <<' '<< edge[x.x].y+1 <<' '<< weight[x.x]<< '\n'; } else { //cout <<'?'<< x.x+1 << ' '<< x.w <<'\n'; for(auto upd : inupd) { if(upd.ind > x.ind) break; //cout << "!" << upd.ind <<' '<<upd.type <<' '<<upd.x <<' '<<upd.w <<'\n'; prevweight[upd.x] = upd.w; } int inittime=DSU::gettime(); for(auto e : used) { if(prevweight[e]<=x.w) { //cout << "+-" << 1+edge[e].x <<' '<< 1+edge[e].y << '\n'; DSU::unite(edge[e].x, edge[e].y); } prevweight[e]=weight[e]; } rez[x.ind] = DSU::query(x.x); DSU::rollback(inittime); } } for(int i = 0; i < qs.size(); i++) { if(qs[i].type == 2) { qs.erase(qs.begin()+i); i--; } } for(int i = l; i <= r; i++) { if(initq[i].type==1) { prevweight[initq[i].x] = weight[initq[i].x] = initq[i].w; } } for(auto &x:inupd) { x.w=weight[x.x]; x.type=3; //cout << ";-;" << x.x << ' '<< x.w <<'\n'; } sort(inupd.begin(),inupd.end()); qs=merge(qs,inupd); //cout << '\n'; //cout << '\n'; } static void fix(int l, int r) { return; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int q; cin >> n >> m; DSU::init(); for(int i = 0; i < m; i++) { cin >> edge[i].x >> edge[i].y >> weight[i]; --edge[i].x; --edge[i].y; weight[i] *= -1; // ca imi convine mai mult cu < decat cu > prevweight[i] = weight[i]; if(edge[i].x > edge[i].y ) { swap(edge[i].x, edge[i].y); } } for(int i = 0; i < m; i++) { //cerr << i<< ' ' << weight[i] <<'\n'; qs.push_back(query{3, i, weight[i], 0}); } sort(qs.begin(),qs.end()); cin >> q; for(int i = 0; i < q; i++) { cin >> initq[i].type >> initq[i].x >> initq[i].w; initq[i].x--; initq[i].w *= -1; initq[i].ind=i; } int buck=sqrt(q); // se poate si mai bine int l=0,r=-1; while(l < q) { r=min(q - 1, r + buck); solve(l,r); fix(l,r); l += buck; } for (int i = 0; i < q; i++) { if(initq[i].type == 2) cout << rez[i] << '\n'; } }

Compilation message (stderr)

bridges.cpp: In function 'void DSU::rollback(int)':
bridges.cpp:59:28: warning: comparison of integer expressions of different signedness: 'std::stack<std::pair<int, int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   59 |     while(undostack.size() > x)
      |                            ^
bridges.cpp: In function 'void solve(int, int)':
bridges.cpp:119:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  119 |   for(int i = 0; i < qs.size(); i++) {
      |                  ~~^~~~~~~~~~~
bridges.cpp:155:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  155 |   for(int i = 0; i < qs.size(); i++) {
      |                  ~~^~~~~~~~~~~
bridges.cpp:118:7: warning: unused variable 'ptr' [-Wunused-variable]
  118 |   int ptr=0;
      |       ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...