Test 6.29 T3 practice simple data structures

Problem Description

Spent a lot of effort, Ben CJK God has finally completed the first three Road title. "Yes, God is indeed a new generation Ben ah!" JesseLiu said with satisfaction, "but you skills in arithmetic is all very well for the use of the data structure, you have to grasp how to do?"

Hear "data structure," the words, even as God CJK Ben can not help but cold sweats. "Young man, now, for me, given a tree, you need to do the following:
1. Modify the weight of a point;
2. the right to query all the points on a path between two points and values;
3. a query tree right ideas and values. "
CJK face flash of disdain:? is not it the title track chain sectional naked
." this is just the first question "JesseLiu this question seems to think too much water, then added:" Finish after all of the above operation, I will have to ask the following:

  1. Asked an idea of ​​how many trees right point less than equal to k;
  2. Inquired about a path between two points in the point of how much weight is smaller than or equal k; "

Although Ben CJK is God, but encountered such a problem, can not help but feel a little fear. Fortunately, through their own metaphysical forces, he contacted his classmates - you. Now, we ask you to A out of water this last question.

Input Format

The first line of a number n, the total number of points. Next, n-1 row, row two integers x and y, expressed edges connected between x and y. Next, an integer m1, Q represents the number of the first operation. Next, the operation represented by line m1, the following format:
"XY. 1" weights is modified to point x y;
"2 XY" query to the right of point x and y on the path (including the x and y);
"x. 3" and right points (including x) x sub-tree query;
next line m2, Q represents the number of second operations. Next, operation is described m2 row, in the following format:
"XYZ. 1" on the path to ask x y is the number of points is smaller than or equal weights Z;
"2 XY" Ask subtree of x how many points is smaller than the weight It is equal to Y;
initial weight of each point is 0.

Output Format

For each inquiry, output represents an integer answer to the query.

Sample input and output

Sample input 1

3
1 2
1 3
3
1 1 3
1 3 1
3 1
2
2 1 2
1 1 3 1

Sample output 1

4
2
1

Sample input 2

5
1 2
1 3
3 4
3 5
5
3 1
1 3 1
2 4 5
1 4 -1
3 3
2
1 1 5 0
2 3 -1

Resolve

For the first question, obviously a chain tree split a single point of query and modify the interval plus bare title, you can do directly.

For the second question, point to produce a contribution, if and only if the point is within the scope of the query (or sub-tree path), resulting contribution to 1. In order to satisfy the constraints, we need to ensure that when asked, in addition to or less than the value of the remaining nodes in a node interrogation values ​​are zero. We can think of, you will be asked to remember in one operation node array together, according to the weight of the first to ask or inquire about the value of small to large order. Each node as a node corresponding to the operation value becomes 1, with the first question asked.

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 500002
using namespace std;
struct opt{
    int op,id,x,y,val;
}a[N];
int head[N],ver[N*2],nxt[N*2],l;
int n,m1,m2,i,dfn[N],end[N],tim,ans[N];
int fa[N],size[N],top[N],son[N],dep[N],pos[N],tree[N],cnt;
void insert(int x,int y)
{
    l++;
    ver[l]=y;
    nxt[l]=head[x];
    head[x]=l;
}
void dfs1(int x)
{
    size[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y!=fa[x]){
            fa[y]=x;
            dep[y]=dep[x]+1;
            dfs1(y);
            if(size[son[x]]<size[y]) son[x]=y;
            size[x]+=size[y];
        }
    }
}
void dfs2(int x,int tp)
{
    dfn[x]=++tim;
    pos[x]=++cnt;top[x]=tp;
    if(son[x]) dfs2(son[x],top[x]);
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y!=son[x]&&y!=fa[x]) dfs2(y,y);
    }
    end[x]=tim;
}
void update(int p,int l,int r,int x,int val)
{
    if(x<l||r<x) return;
    if(l==r){
        tree[p]=val;
        return;
    }
    int mid=(l+r)/2;
    update(p*2,l,mid,x,val);
    update(p*2+1,mid+1,r,x,val);
    tree[p]=tree[p*2]+tree[p*2+1];
}
int ask(int p,int l,int r,int ql,int qr)
{
    if(r<ql||l>qr) return 0;
    if(l>=ql&&r<=qr) return tree[p];
    int mid=(l+r)/2;
    return ask(p*2,l,mid,ql,qr)+ask(p*2+1,mid+1,r,ql,qr);
}
int find(int u,int v)
{
    int f1=top[u],f2=top[v],ans=0;
    while(f1!=f2){
        if(dep[f1]<dep[f2]) swap(f1,f2),swap(u,v);
        ans+=ask(1,1,n,pos[f1],pos[u]);
        u=fa[f1];f1=top[u];
    }
    if(dep[u]>dep[v]) swap(u,v);
    return ans+ask(1,1,n,pos[u],pos[v]);
}
int my_comp(const opt &a,const opt &b)
{
    if(a.val==b.val) return a.op<b.op;
    return a.val<b.val;
}
int main()
{
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    cin>>n;
    for(i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        insert(u,v);
        insert(v,u);
    }
    dfs1(1);
    dfs2(1,1);
    cin>>m1;
    for(i=1;i<=m1;i++){
        int op,x,y;
        cin>>op;
        if(op==1){
            cin>>x>>y;
            update(1,1,n,pos[x],y);
        }
        else if(op==2){
            cin>>x>>y;
            cout<<find(x,y)<<endl;
        }
        else{
            cin>>x;
            cout<<ask(1,1,n,dfn[x],end[x])<<endl;
        }
    }
    cin>>m2;
    int tmp=m2;
    for(i=1;i<=m2;i++){
        int op,x,y,z;
        cin>>op;
        if(op==1){
            cin>>x>>y>>z;
            a[i]=(opt){op,i,x,y,z};
        }
        else{
            cin>>x>>y;
            a[i]=(opt){op,i,x,0,y};
        }
    }
    for(i=1;i<=n;i++) a[++m2]=(opt){0,m2,i,0,ask(1,1,n,pos[i],pos[i])};
    memset(tree,0,sizeof(tree));
    sort(a+1,a+m2+1,my_comp);
    for(i=1;i<=m2;i++){
        if(a[i].op==0) update(1,1,n,pos[a[i].x],1);
        else if(a[i].op==1) ans[a[i].id]=find(a[i].x,a[i].y);
        else ans[a[i].id]=ask(1,1,n,dfn[a[i].x],end[a[i].x]);
    }
    for(i=1;i<=tmp;i++) cout<<ans[i]<<endl;
    fclose(stdin);
    fclose(stdout);
    return 0;
}

to sum up

One idea: In order to eliminate the influence, can make an impact after the interrogation, and by ordering the appropriate transformation implemented.

Guess you like

Origin www.cnblogs.com/LSlzf/p/11111745.html