首页 > 代码库 > [题解]某模拟题题解

[题解]某模拟题题解

技术分享

技术分享


  第一道题还是比较简单,只不过做的时候手贱写错了一个字母,然后活活RE掉了40分

  先处理处最终的图,然后从后往前用并查集完成询问。至于之前的删边可以排个序,

然后建一个长度和它一样的boolean数组标志这条边又没被删,删除的时候就lower_bound

就可以了,只不过注意重复的边。如果这一位上为false(这条边被删掉了)应该往后找到

第一个为true的地方,然后将它改为false


Code:

  1 #include<iostream>  2 #include<cstdio>  3 #include<fstream>  4 #include<cstdlib>  5 #include<queue>  6 #include<set>  7 #include<map>  8 #include<cctype>  9 #include<algorithm> 10 #include<cstring> 11 #include<string> 12 #include<stack> 13 using namespace std; 14 typedef bool boolean; 15 #define smin(a, b) a = min(a, b) 16 #define smax(a, b) b = max(a, b) 17 template<typename T> 18 inline void readInteger(T& u) { 19     char x; 20     while(!isdigit(x = getchar())); 21     for(u = x - 0; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - 0); 22     ungetc(x, stdin); 23 } 24  25 typedef class union_found{ 26     public: 27         int *f; 28         union_found():f(NULL) {} 29         union_found(int points) { 30             f = new int[(const int)(points + 1)]; 31             for(int i = 0; i <= points; i++) 32                 f[i] = i; 33         } 34         int find(int x) { 35             if(f[x] != x)    return f[x] = find(f[x]); 36             return f[x]; 37         } 38         void unit(int fa, int so) { 39             int ffa = find(fa); 40             int fso = find(so); 41             f[fso] = ffa; 42         } 43         boolean connected(int a, int b) { 44             return find(a) == find(b); 45         } 46 }union_found; 47  48 typedef class _edge{ 49     public: 50         int from; 51         int end; 52         _edge(const int a = 0, const int b = 0) { 53             from = min(a, b); 54             end = max(a, b); 55         } 56         boolean operator <(_edge another) const { 57             if(this->from != another.from)    return this->from < another.from; 58             return this->end < another.end; 59         } 60 }_edge; 61  62 typedef class _question{ 63     public: 64         boolean isCut; 65         int a; 66         int b; 67 }_question; 68  69 inline void readQues(_question& que){ 70     int c; 71     readInteger(c); 72     if(c == 1)    que.isCut = true; 73     else que.isCut = false; 74     readInteger(que.a); 75     readInteger(que.b); 76 } 77  78 int n, m, q; 79 union_found uf; 80 _edge* es; 81 boolean* enable; 82 _question *ques; 83 stack<int> s; 84  85 #define MAP_IT multiset<_edge>::iterator 86  87 inline void init() { 88     int lastEdge; 89     readInteger(n); 90     readInteger(m); 91     readInteger(q); 92     es = new _edge[(const int)(m + 1)]; 93     uf = union_found(n); 94     ques = new _question[(const int)(q + 1)]; 95     enable = new boolean[(const int)(m + 1)]; 96     lastEdge = m; 97     memset(enable, true, sizeof(boolean) * (m + 1)); 98     for(int i = 1, a, b; i <= m; i++){ 99         readInteger(a);100         readInteger(b);101         es[i] = _edge(a, b);102     }103     sort(es + 1, es + m + 1);104     for(int i = 1; i <= q; i++){105         readQues(ques[i]);106         ques[i].a ^= lastEdge;107         ques[i].b ^= lastEdge;108         if(ques[i].isCut){109 //            es.erase(es.lower_bound(_edge(ques[i].a, ques[i].b)));110             int rank = lower_bound(es + 1, es + m + 1, _edge(ques[i].a, ques[i].b)) - es;111             while(!enable[rank]) rank++;112             enable[rank] = false;113             lastEdge--;114         }115     }116     for(int i = 1; i <= m; i++){117         if(enable[i])118             uf.unit(es[i].from, es[i].end);119     }120 }121 122 void solve() {123     for(int i = q; i > 0; i--){124         if(ques[i].isCut){125             uf.unit(ques[i].a, ques[i].b);126         }else{127             boolean result = uf.connected(ques[i].a, ques[i].b);128             if(result)    s.push(1);129             else s.push(0);130         }131     }132     while(!s.empty()){133         printf("%d\n", s.top());134         s.pop();135     }136 }137 138 int main(){139     freopen("graph.in", "r", stdin);140     freopen("graph.out", "w", stdout);141     init();142     solve();143     fclose(stdin);144     fclose(stdout);145     return 0;146 }

技术分享

技术分享


  第二道相对于第一道题就没有那么友好了,这次真的只能用在线算法,于是我决定用暴力碰碰运气

结果真的AC了。。。(这数据太水,没办法)

  思路很简单,这道题是树,所以,两点之间的连线断开后,就成了两个联通块,然后我给每个连通块

一个编号,然后每次删边就去dfs一遍修改这个值。


 

Code

  1 #include<iostream>  2 #include<cstdio>  3 #include<fstream>  4 #include<cstdlib>  5 #include<queue>  6 #include<set>  7 #include<map>  8 #include<cctype>  9 #include<algorithm> 10 #include<cstring> 11 #include<string> 12 using namespace std; 13 typedef bool boolean; 14 #define smin(a, b) a = min(a, b) 15 #define smax(a, b) b = max(a, b) 16 template<typename T> 17 inline void readInteger(T& u) { 18     char x; 19     while(!isdigit(x = getchar())); 20     for(u = x - 0; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - 0); 21     ungetc(x, stdin); 22 } 23  24 ///Linked Map Template Starts 25 typedef class Edge{ 26     public: 27         int next; 28         int end; 29         Edge(const int next = 0, const int end = 0):next(next), end(end){    } 30 }Edge; 31 typedef class MapManager{ 32     public: 33         int *h; 34         Edge* edge; 35         int ce; 36         MapManager():h(NULL), edge(NULL), ce(0) { } 37         MapManager(int point, int edges):ce(0){ 38             h = new int[(const int)(point + 1)]; 39             edge = new Edge[(const int)(edges + 1)]; 40             memset(h, 0, sizeof(int) * (point + 1)); 41         } 42         inline void addEdge(int from, int end) { 43             edge[++ce] = Edge(h[from], end); 44             h[from] = ce; 45         } 46 }MapManager; 47 ///Linked Map Template Ends 48  49 int n, q; 50 MapManager tree; 51 int* fa; 52 int* value; 53 int* types; 54 int ct; 55  56 inline void init() { 57     ct = 1; 58     readInteger(n); 59     readInteger(q); 60     value = http://www.mamicode.com/new int[(const int)(n + 1)]; 61     fa = new int[(const int)(n + 1)]; 62     tree = MapManager(n, 2 * n); 63     types = new int[(const int)(n + 1)]; 64     fill(types + 1, types + n + 1, 1); 65     for(int i = 1; i <= n; i++)    readInteger(value[i]); 66     for(int i = 1, a, b; i < n; i++){ 67         readInteger(a); 68         readInteger(b); 69         tree.addEdge(a, b); 70         tree.addEdge(b, a); 71     } 72 } 73  74 void buildTree(int node, int lastNode){ 75     fa[node] = lastNode; 76     for(int i = tree.h[node]; i != 0; i = tree.edge[i].next){ 77         int& end = tree.edge[i].end; 78         if(end == lastNode)    continue; 79         buildTree(end, node); 80     } 81 } 82  83 void update(int node, int lastNode, const int newType){ 84     if(fa[node] != lastNode) return; 85     types[node] = newType; 86     for(int i = tree.h[node]; i != 0; i = tree.edge[i].next){ 87         int& end = tree.edge[i].end; 88         if(end == lastNode)    continue; 89         update(end, node, newType); 90     } 91 } 92  93 int lastans; 94  95 inline void solve() { 96     buildTree(1, 0); 97     for(int i = 1, c, a, b; i <= q; i++){ 98         readInteger(c); 99         readInteger(a);100         readInteger(b);101         a ^= lastans;102         b ^= lastans;103         int s;104         switch(c){105         case 1:106             if(fa[a] == b){107                 s = a;108             }else{109                 s = b;110             }111             fa[s] = 0;112             update(s, 0, ++ct);113             break;114         case 2:115             if(types[a] == types[b]){116                 lastans = value[a] * value[b];117             } else {118                 lastans = value[a] + value[b];119             }120             printf("%d\n", lastans);121             break;122         case 3:123             value[a] = b;124             break;125         default:126 //            throw c;127             break;128         }129     }130 }131 132 int main(){133     freopen("tree.in", "r", stdin);134     freopen("tree.out", "w", stdout);135     init();136     solve();137     return 0;138 }

技术分享

技术分享


  第三题,也是最简单的一道,直接Tarjan搜强连通分量不解释

Code

  1 #include<iostream>  2 #include<cstdio>  3 #include<fstream>  4 #include<cstdlib>  5 #include<queue>  6 #include<set>  7 #include<map>  8 #include<stack>  9 #include<cctype> 10 #include<algorithm> 11 #include<cstring> 12 #include<string> 13 using namespace std; 14 typedef bool boolean; 15 #define smin(a, b) a = min(a, b) 16 #define smax(a, b) b = max(a, b) 17 template<typename T> 18 inline void readInteger(T& u) { 19     char x; 20     while(!isdigit(x = getchar())); 21     for(u = x - 0; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - 0); 22     ungetc(x, stdin); 23 } 24 ///Linked Map Template Starts 25 typedef class Edge{ 26     public: 27         int next; 28         int end; 29         Edge(const int next = 0, const int end = 0):next(next), end(end){    } 30 }Edge; 31 typedef class MapManager{ 32     public: 33         int *h; 34         Edge* edge; 35         int ce; 36         MapManager():h(NULL), edge(NULL), ce(0) { } 37         MapManager(int point, int edges):ce(0){ 38             h = new int[(const int)(point + 1)]; 39             edge = new Edge[(const int)(edges + 1)]; 40             memset(h, 0, sizeof(int) * (point + 1)); 41         } 42         inline void addEdge(int from, int end) { 43             edge[++ce] = Edge(h[from], end); 44             h[from] = ce; 45         } 46 }MapManager; 47 ///Linked Map Template Ends 48  49 MapManager g; 50 long long result; 51  52 stack<int> s; 53 boolean* visited; 54 boolean* inStack; 55 int counter; 56 int *visitID; 57 int *exitID; 58  59 inline void getMap(int end){ 60     int c_m = 0; 61     int node; 62     do{ 63         node = s.top(); 64         s.pop(); 65         inStack[node] = false; 66         c_m++; 67     }while(node != end); 68     result += c_m * 1LL * (c_m - 1) / 2; 69 } 70  71 void Tarjan(int node){ 72     visited[node] = true; 73     visitID[node] = exitID[node] = ++counter; 74     s.push(node); 75     inStack[node] = true; 76     for(int i = g.h[node]; i != 0; i = g.edge[i].next){ 77         int e = g.edge[i].end; 78         if(!visited[e]) { 79             Tarjan(e); 80             smin(exitID[node], exitID[e]); 81         } else if(inStack[e]) { 82             smin(exitID[node], visitID[e]); 83         } 84     } 85     if(visitID[node] == exitID[node]) 86         getMap(node); 87 } 88  89 int n; 90 int m; 91  92 inline void init() { 93     readInteger(n); 94     readInteger(m); 95     g = MapManager(n, m); 96     visited = new boolean[(const int)(n + 1)]; 97     inStack = new boolean[(const int)(n + 1)]; 98     visitID = new int[(const int)(n + 1)]; 99     exitID = new int[(const int)(n + 1)];100     memset(visited, false, sizeof(boolean) * (n + 1));101     memset(inStack, false, sizeof(boolean) * (n + 1));102     for(int i = 1, a, b; i <= m; i++) {103         readInteger(a);104         readInteger(b);105         g.addEdge(a, b);106     }107 }108 109 inline void solve() {110     for(int i = 1; i <= n; i++) {111         if(!visited[i])112             Tarjan(i);113     }114     cout<<result;115 }116 117 int main(){118     freopen("logic.in", "r", stdin);119     freopen("logic.out", "w", stdout);120     init();121     solve();122     return 0;123

[题解]某模拟题题解