[Ioi2018]werewolf Werewolf--kruskal Reconstruction tree + Persistent segment tree

Source: Internet
Author: User

Topic Links:

Ioi2018werewolf

The title of the number is starting from 0, too uncomfortable, we numbered from 1 to start speaking qaq.

The main idea is to ask each time from a point to walk only the points numbered in [L,n], at any point into a wolf, and then can only walk [0,r] points, whether to reach another point.

The latter part is actually to find out what points only go [0,r] in the point can reach the end, then in turn, is the end only to go [0,r] points can reach which points.

Then there is a solution as long as there is a intersection between the point at which the beginning can reach and the point at which the endpoint can reach.

Because the starting point can only go to some of the larger number of points, then we find the largest generation tree of the original image, build a kruskal to reconstruct the tree, find the DFS sequence of the reconstruction tree, each query in the reconstruction tree to multiply find can reach the link block in the DFS sequence of the interval is good.

Instead, the smallest spanning tree of the original image is obtained from the finish line, and is then searched as described above.

Once two sections of the DFS sequence are found, they can be solved with the same points in the two intervals.

We use the position of each point in the first DFS sequence as the horizontal axis, and the position in the second DFS sequence as the ordinate, and the rest is a simple two-dimensional point problem.

Wait, is it almost something up there? The original is not Benquan ah?

As an example of the largest spanning tree, for an edge (x, y), two points can reach each other by this edge, determined by the smaller points in the two points, so each edge edge is the smaller of the sides of the edge when the maximum spanning tree is obtained. The minimum spanning tree edge is the larger of the two ends.

The whole idea is to construct the reconstructed tree of the minimum spanning tree and the largest spanning tree, respectively, to find the DFS ordinal position of each point in two reconstruction trees, and then to persist the two-dimension points of the segment tree.

Kruskal refactoring tree here will not be repeated, if not too understanding can refer to my other blog NOI2018 return journey , the problem and the idea is very similar.

The surface does not seem to guarantee that the whole map is connected, so it may be kruskal to reconstruct the forest.

#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <cstdio> #include <vector> #include <bitset> #include <cstring> #include <iostream># Include<algorithm> #define LL Long longusing namespace std;struct miku{int u,v,x,y;} A[400010];int cnt;int n,m,k;int s,t,l,r;int num1,num2;int sum1,sum2;int s1[400010];int s2[400010];int t1[400010];int T2 [400010];int q1[400010];int q2[400010];int v1[400010];int v2[400010];int fa1[400010];int fa2[400010];int ls1[400010]; int rs1[400010];int ls2[400010];int rs2[400010];int ls[5000010];int rs[5000010];int vis1[400010];int vis2[400010];int Sum[5000010];int root[200010];int f1[400010][18];int f2[400010][18];int find1 (int x) {if (fa1[x]==x) {return    X } return Fa1[x]=find1 (Fa1[x]);}    int find2 (int x) {if (fa2[x]==x) {return x; } return Fa2[x]=find2 (Fa2[x]);} BOOL Cmp1 (Miku A,miku b) {return a.x>b.x;} BOOL Cmp2 (Miku A,miku b) {return A.y<b.y;}    void build (int &rt,int l,int r) {rt=++cnt;    if (l==r) {return;    } int mid= (L+R) >>1;    Build (Ls[rt],l,mid); Build (Rs[rt],mid+1,r);}    void Updata (int &rt,int pre,int l,int r,int k) {rt=++cnt;    sum[rt]=sum[pre]+1;    if (l==r) {return;    } Ls[rt]=ls[pre];    Rs[rt]=rs[pre];    int mid= (L+R) >>1;    if (k<=mid) {updata (ls[rt],ls[pre],l,mid,k);    } else {updata (rs[rt],rs[pre],mid+1,r,k);    }}int query (int x,int y,int l,int r,int l,int R) {if (l<=l&&r<=r) {return sum[y]-sum[x];    } int mid= (L+R) >>1;    int res=0;    if (l<=mid) {res+=query (ls[x],ls[y],l,mid,l,r);    } if (R>mid) {res+=query (rs[x],rs[y],mid+1,r,l,r); } return res;    void dfs1 (int x) {vis1[x]=1;    S1[X]=SUM1;    if (x<=n) {q1[++sum1]=x;    } for (int i=1;i<=17;i++) {f1[x][i]=f1[f1[x][i-1]][i-1];     } if (Ls1[x]) {   DFS1 (Ls1[x]);    } if (Rs1[x]) {DFS1 (rs1[x]); } T1[X]=SUM1;}    void dfs2 (int x) {vis2[x]=1;    s2[x]=sum2;    if (x<=n) {q2[++sum2]=x;    } for (int i=1;i<=17;i++) {f2[x][i]=f2[f2[x][i-1]][i-1];    } if (Ls2[x]) {DFS2 (ls2[x]);    } if (Rs2[x]) {DFS2 (rs2[x]); } t2[x]=sum2;}            int ST1 (int x,int val) {for (int i=17;i>=0;i--) {if (v1[f1[x][i]]>=val&&f1[x][i]!=0) {        X=f1[x][i]; }} return x;}            int ST2 (int x,int val) {for (int i=17;i>=0;i--) {if (v2[f2[x][i]]<=val&&f2[x][i]!=0) {        X=f2[x][i]; }} return x;}    int main () {scanf ("%d%d%d", &n,&m,&k);        for (int i=1;i<=m;i++) {scanf ("%d%d", &AMP;A[I].U,&AMP;A[I].V);        a[i].u++;        a[i].v++;        A[i].x=min (A[I].U,A[I].V);    A[i].y=max (A[I].U,A[I].V);        } for (int i=1;i<2*n;i++) {fa1[i]=i; fa2[i]=I    } num1=num2=n;    Sort (A+1,A+1+M,CMP1);        for (int i=1;i<=m;i++) {int fx=find1 (A[I].U);        int Fy=find1 (A[I].V);            if (fx!=fy) {num1++;            v1[num1]=a[i].x;            LS1[NUM1]=FX;            Rs1[num1]=fy;            F1[FX][0]=NUM1;            F1[FY][0]=NUM1;            FA1[FX]=NUM1;            FA1[FY]=NUM1;            if (num1==2*n-1) {break;        }}} for (int i=1;i<=n;i++) {if (!vis1[i]) {DFS1 (Find1 (i));    }} sort (A+1,A+1+M,CMP2);        for (int i=1;i<=m;i++) {int fx=find2 (A[I].U);        int Fy=find2 (A[I].V);            if (fx!=fy) {num2++;            V2[NUM2]=A[I].Y;            LS2[NUM2]=FX;            Rs2[num2]=fy;            f2[fx][0]=num2;            f2[fy][0]=num2;            fa2[fx]=num2;            fa2[fy]=num2;            if (num2==2*n-1) {break; }}} for (int i=1;i<=n;i++) {if (!vis2[i]) {DFS2 (Find2 (i));    }} build (Root[0],1,n);    for (int i=1;i<=n;i++) {updata (root[i],root[i-1],1,n,s2[q1[i]]+1);        } while (k--) {scanf ("%d%d%d%d", &s,&t,&l,&r);        s++;        t++;        l++;        r++;        S=st1 (s,l);        T=st2 (T,R);        int Ans=query (root[s1[s]],root[t1[s]],1,n,s2[t]+1,t2[t]);        if (ans==0) {printf ("0\n");        } else {printf ("1\n"); }    }}

[Ioi2018]werewolf Werewolf--kruskal tree + persistent segment tree

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.