【SCOI2011 Day2】Tricky operation

Problem Description

There are N nodes, numbered from 1 to N, and these N nodes are disconnected from each other at first. The initial weight of the i-th node is a[i], and then there are the following operations:
U xy: Add an edge to connect the x-th node and the y-th node
A1 xv: Increase the weight of the x-th node v
A2 xv: Increase the weights of all nodes in the connected block where the xth node is located v
A3 v: Increase the weights of all nodes v
F1 x: Output the current weight of the xth node
F2 x: Output In the connected block where the xth node is located, the weight of the node with the largest weight
F3: output the weight of the node with the largest weight among all nodes

input format

  The first line of input is an integer N, representing the number of nodes.
  The next line inputs N integers, a[1], a[2], …, a[N], representing the initial weights of N nodes.
  Enter an integer Q on the next line, representing the next operand.
  Finally, enter the Q line, the format of each line is as shown in the title description.

output format

  For operations F1, F2, and F3, output the corresponding results, each of which occupies a row.

sample input

3
0 0 0
8
A1 3 -20
A1 2 20
U 1 3
A2 1 10
F1 3
F2 3
A3 -10
F3

Sample output

-10
10
10

data range

For 30% of the data, guarantee N<=100, Q<=10000
For 80% of the data, guarantee N<=100000, Q<=100000
For 100% of the data, guarantee N<=300000, Q<=300000
For all The data is guaranteed to be valid, and -1000<=v, a[1], a[2], …, a[N]<=1000


answer

Let's maintain a sloping heap.
Merge operation and A3 will not be said.
Let's do A2 first. Just place a Lzay marker on top of the stack. However, in order to ensure the decentralization of the mark, every time in GetFather, all the points from the point to the top of the heap must be placed under the mark (for details, see the gf() function in the code).
Let's delete A1 first and then add it. Find the top of the pile of this point (drop the marker in the process), merge the left and right sons of it (the modified point), and then connect its left and right sons to its father. Modify that point again, merging it with the top of the heap.
Don't say F1 and F2, just pay attention to the decentralization mark.
F3. . . This konjac can't use set and multset, so it uses a magical method called "garbage heap". Put the points before each modification into the Trash priority queue, and put the modified points into the Query priority queue. Faced with the query, as long as the largest element of both queues is the same, delete them (because it doesn't exist anymore). Is it mysterious?
All in all, this is a tricky operation. Too tricky.


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <cstring>
using namespace std;
priority_queue<int> qu,tr;
const int Q=666666;
int ls[Q],rs[Q],v[Q],f[Q],lazy[Q],n;
void pd(int x)
{
    if((!lazy[x])||(!x))return;
    if(ls[x])v[ls[x]]+=lazy[x],lazy[ls[x]]+=lazy[x];
    if(rs[x])v[rs[x]]+=lazy[x],lazy[rs[x]]+=lazy[x];
    lazy[x]=0;
}
int merge(int x,int y)
{
    if((!x)||(!y))return x|y;
    pd(x),pd(y);
    if(v[x]<v[y])swap(x,y);
    rs[x]=merge(rs[x],y);
    f[rs[x]]=x;
    swap(ls[x],rs[x]);
    return x;
}
stack<int> st;
int gf(int x)
{
    int WDWDF=x;
    st.push(x);
    while(f[x]){
        x=f[x];
        WDWDF=x;
        st.push(x);
    }
    while(st.size())pd(st.top()),st.pop();
    return WDWDF;
}
int del(int x)
{
    int lls=ls[x],rrs=rs[x],y,fa=f[x],ha;
    ha=gf(x);
    y=merge(lls,rrs);
    ls[x]=rs[x]=f[x]=0;
    if(ls[fa]==x)ls[fa]=y;
    else rs[fa]=y;
    f[y]=fa;
    return gf(y);
}
int main()
{
    char o;
    int i,x,y,m,fx,fy,all=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%d",&v[i]),f[i]=0,qu.push(v[i]);
    for(scanf("%d",&m);m;--m)
        while(true)
        {
            o=getchar();
            if(o=='A')
            {
                scanf("%d",&i);
                if(i==3){
                    scanf("%d",&x);
                    all+=x;
                }else
                if(i==1){
                    scanf("%d%d",&x,&y);
                    int a=gf(x);
                    tr.push(v[a]);
                    v[x]+=y;
                        qu.push(v[merge(del(x),x)]);

                }else
                if(i==2){
                    scanf("%d%d",&x,&y);
                    x=gf(x);
                    tr.push(v[x]);
                    v[x]+=y;
                    lazy[x]+=y;
                    qu.push(v[x]);
                }
                break;
            }
            if(o=='F')
            {
                scanf("%d",&i);
                if(i==3){
                    while(qu.size()&&tr.size()&&qu.top()==tr.top())
                    qu.pop(),tr.pop();
                    printf("%d\n",qu.top()+all);
                }else
                if(i==2){
                    scanf("%d",&x);
                    printf("%d\n",v[gf(x)]+all);
                }else{
                    scanf("%d",&x);
                    gf(x);
                    printf("%d\n",v[x]+all);
                }
                break;
            }
            if(o=='U')
            {
                scanf("%d%d",&x,&y);
                x=gf(x),y=gf(y);
                if(x!=y){
                    tr.push(v[x]),tr.push(v[y]);
                    qu.push(v[merge(x,y)]);
                }
                break;
            }
        }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325492077&siteId=291194637