Qaq lis Tree, Lis tree, Qaq 2

Source: Internet
Author: User

These two questions are actually a question in the exam Owo

It's horrible, I've been busy for three hours, and I wrote a full 7K.

This question two asks the correlation is not strong, therefore separates to consider

Lis Tree of Qaq

Consider how to solve the answer with DP

Set DP (v) to indicate V to root of the modified sequence and C (v) is V point right

Then the answer to V is DP (v) minus V to Root point and

The most intuitive idea is that we jump from the V-point up to the father, jumping to the first without modifying the point U

It is not difficult to find that since U is not modified, the sequence after the sequence and U is exactly the same

can be transferred directly to V, then the value of DP (v) is the sequence of DP (U) and V->u and the

Notice that all the points of v->u are bound to be modified, so its sequence must be C (v), C (v) +1,c (v) +2 ...

This sequence and the direct arithmetic progression sum can be

accurately describe the u if you want to modify it should be changed to C (v) +dep (v)-dep (u)

If u do not modify then satisfy C (u) >c (v) +dep (v)-dep (u)

After moving the term C (u) +dep (u) >c (v) +dep (v), that is to find the first point to meet this condition

So it's clear that the first way to find the one you don't need to modify is to handle multiplying array multiplication

Considering the effect of the modification, it is not difficult to find a modification that affects a subtrees tree, and if we refactor the subtree violently, the complexity of time explodes.

We can consider the tree chunking, dividing the tree into blocks, and we define the smallest point in the block as the root of the block (it can be shown that each block has and only one of these points)

We maintain four of information for each point

The first message is the modified sequence of the point to the root of the block and

The second message is the weight of the root after the point has been modified (it is not difficult to find this information also satisfies the DP nature)

The third message is this point to the root of the point right and

The fourth message is the multiplying array of points up

Consider stitching between blocks and blocks per query

Because of the second message we recorded, when we jumped to the block above, it was easy to determine whether the current point would need to be modified after joining the previous block.

If you do not need to modify it, proceed directly to the root of the current block

Otherwise we will not be difficult to get the current point needs to be modified to the value, with the above method multiplication to find the first no need to modify the point and update the answer can be

Finally with the modified sequence and minus the point right and that's the answer.

Consider the impact of the modification

Every time we modify, we just need to refactor the information inside the block.

For the third message, DFS can take care of it. The fourth information refactoring multiplication array

The first and second information utilizes the reconstructed multiplication array to recalculate

This solves this problem in the time of O (m*sqrt (n) *log (n)).

But the constants are small, so they run fast.

Lis Tree of Qaq 2

Listen to He Shin said this topic can be used offline + line tree merge to engage, but Konjac Konjac IQ low, and did not understand

So I yy a can online O (nlog^2n) practice

This inquiry is better than the last question.

We consider how a subtrees tree is legal, when and only if all the sides of the subtrees tree are present.

But if we use 0/1 to indicate existence, the maximum value of a global solution can become very troublesome.

We might as well turn all the illegal solutions into values that cannot be queried at the maximum value, so we can query the maximum value directly.

This is how we assign each edge a weight greater than N, and each point starts with its own subtree size.

When an edge becomes illegal from the law, we subtract this weight from all the points on the edge.

When an edge is never legally legal, we add this weight to all the points on the side of the line.

It is not difficult to find that the weight of a point is a positive integer when and only if all edges in the subtree are valid

Otherwise, because sz<=n, as long as there is an edge is not legal, all of its above points will be subtracted from a >n value into a negative number

This is easy to maintain by using a tree chain to split the line tree.

Then the query is very simple, we only need to ask for the global maximum (because the illegal solution is not possible as the optimal solution)

For the changes, we find that each modification is a point right, so it's not just a side that affects

But we will find that we can divide the affected sides into two categories, one is the current point to the edge of the son, the other is the current point to the father's side

It is not difficult to find that the first type of edge may be a lot, but the points affected are the same.

We just need to figure out the synthesis of these effects, that is, to query the weights and values of the illegal edges before and after the change.

The illegal side must satisfy the C (v) >=c (u), we maintain the son's information with the balance tree for each point with C as the key value

So each time in the balance tree directly on the right, by the way to change their father's corresponding balance tree

Then judge whether the current point to the father's side has changed and corresponding changes can be

Time complexity O (nlog^2n)

Put down the code, two problems in one force with namespace to gather together

#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include < Algorithm>using namespace Std;typedef long long ll;const int maxn=100010;const LL oo=1ll<<60;int n,m,f,u,v,blo; int H[maxn],cnt=0;int Fa[maxn],top[maxn],son[maxn];int W[maxn],pos[maxn],fp[maxn],tot=0;int co[maxn],rt[maxn];bool Vis[maxn];int dep[maxn];struct edge{int To,next;} G[MAXN]; LL C[MAXN],SZ[MAXN]; LL add[maxn<<2]; LL mx[maxn<<2]; LL xp[maxn];void Add (int x,int y) {++cnt; G[cnt].to=y; g[cnt].next=h[x];h[x]=cnt;} void read (int &num) {Num=0;char Ch=getchar (); while (ch< '! ') Ch=getchar (); while (ch>= ' 0 ' &&ch<= ' 9 ') num=num*10+ch-' 0 ', Ch=getchar ();} struct Splay_tree{int fa[maxn],c[maxn][2]; LL S[MAXN],VAL[MAXN],V[MAXN]; #define FA (i) fa[i] #define C (x,i) C[x][i] #define S (i) s[i] #define VAL (i) val[i]void up (int u {if (!u) return;s (U) =s (c (u,0)) +s (c (u,1)) +val (u);} void rotate (int p,int x) {int mark= p==c (x,1), Y=c (p,mark^1), Z=FA (x), if (C (z,0) ==x) C (z,0) =p;if (c (z,1) ==x) C (z, 1) =p;if (y) fa (y) =x;fa (P) =z;c (p,mark^1) =X;FA (x) =p;c (X,mark) =y;up (x);} void splay (int p,int k,int &rt) {while (FA (p)!=k) {int X=fa (p), Y=FA (x), if (y==k) rotate (p,x), Else if (P==c (x,0) ^x==c (y , 0)) rotate (p,x), rotate (p,y); else rotate (x, y), rotate (p,x);} Up (P); if (!k) rt=p;} void Insert (int u,int &rt) {int Now=rt,f=now;while (now) {f=now;if (C[u]>v[now]) now=c (now,1); else Now=c (now,0);} FA (U) =f; V[u]=c[u];val (U) =s (u) =co[u];if (f) C (F,c[u]>v[f]) =u; Splay (U,0,RT);} void del (int u,int &rt) {splay (U,0,RT), if (!c (u,0)) {rt=c (u,1); FA (RT) =0;c (u,1) =0;return;} int Now=c (u,0), while (C (now,1)) now=c (now,1); Splay (NOW,U,RT), FA (now) =0;c (u,0) =0;rt=now;fa (c (u,1)) =now;c (now,1) =c (u,1), C (u,1) =0;up (now); int Get_pre (LL v,int &rt) {int Now=rt,p=-1;while (now) {if (v[now]<v) p=now,now=c (now,1); else Now=c (now,0);} return p;} ll ask (ll V,int &rt) {int Pre=get_pre (V,RT), if (Pre==-1) return S (RT); Splay (PRE,0,RT); return s (C (rt,1));} void DFS (int u) {if (!u) Return;dfs (c (u,0));p rintf ("%lld", V[u]);D FS (c (u,1));}} T;namespace s{void DFS (int U,int f) {w[u]=1;sz[u]=co[u];for (int i=h[u];i;i=g[i].next) {int v=g[i].to;if (v==f) Continue;dep[v]=dep[u]+1;dfs (v , u); w[u]+=w[v];sz[u]+=sz[v];if (W[son[u]]<w[v]) son[u]=v;} return;} void Get_pos (int u,int f) {top[u]=f;pos[u]=++tot;fp[tot]=u;if (!son[u]) return; Get_pos (son[u],f); for (int i=h[u];i;i=g[i].next) {int v=g[i].to;if (v==f| | V==son[u]) continue; Get_pos (v,v);} return;} void Get_splay (int u,int f) {for (int i=h[u];i;i=g[i].next) {int v=g[i].to;if (V==F) continue; T.insert (V,rt[u]); Get_splay (v,u);} return;} void build (int o,int l,int R) {if (l==r) {Mx[o]=sz[fp[l]];return;} int mid= (L+R) >>1;build (O<<1,l,mid); build (O<<1|1,mid+1,r); Mx[o]=max (mx[o<<1],mx[o< <1|1]);} void Push_down (int o,int l,int r) {mx[l]+=add[o];add[l]+=add[o];mx[r]+=add[o];add[r]+=add[o];add[o]=0;} void UPD (int o,int l,int r,int x,int y,ll v) {if (l>=x&&r<=y) {Mx[o]+=v;add[o]+=v;return;} int mid= (L+R) >>1;int l= (o<<1), r= (l|1), if (add[o]!=0) Push_down (o,l,r), if (Y<=mid) UPD (o<<1,l, Mid,x, y,v), else if (x>mid) upd (o<<1|1,mid+1,r,x,y,v), Else upd (o<<1,l,mid,x,y,v), UPD (o<<1|1,mid+1,r , x,y,v); Mx[o]=max (mx[o<<1],mx[o<<1|1]);} void Get_add (int u,ll v) {while (U) {UPD (1,1,n,pos[top[u]],pos[u],v); u=fa[top[u]];} return;} void get_modify (int u,ll v) {LL now=t.ask (V,rt[u])-t.ask (C[u],rt[u]); UPD (1,1,n,pos[u],pos[u],now), if (Fa[u]) {if (C[u]>=c[fa[u]) now-=co[u];if (V>=c[fa[u]]) now+=co[u]; T.del (U,rt[fa[u]); c[u]=v; T.insert (U,rt[fa[u]); Get_add (Fa[u],now);} C[u]=v;return;}}; namespace C{int anc[maxn][10]; LL Mx[maxn][20];int RT[MAXN],SZ[MAXN],DEP[MAXN]; LL go[maxn],co[maxn],s[maxn];void get_block (int u,int f) {if (Sz[rt[f]]==blo) Rt[u]=u,sz[u]=1;else sz[rt[f]]++,rt[u]= rt[f];for (int i=h[u];i;i=g[i].next) {int v=g[i].to;if (v==f) continue;dep[v]=dep[u]+1; Get_block (v,u);} return;} void Get_pre (int u,int v) {int now=dep[u]-dep[v];anc[u][0]=fa[u];mx[u][0]=c[u]+dep[u];for (int i=1; (1<< (I-1)) <=now;++i) {if (anc[u][i-1]!=-1) {int a=anc[u][i-1];anc[u][i]=anc[a][i-1];mx[u][i]=Max (mx[u][i-1],mx[a][i-1]);}} return;} int get_mx (int u,int v,int w) {int log,now=dep[u]-dep[v];for (log=0; (1<<log) <=now;++log);--log;for (int i=log; I>=0;--i) {if (anc[u][i]!=-1&&mx[u][i]<=w) u=anc[u][i];} if (c[u]+dep[u]<=w) return-1;if (dep[u]<dep[v]) Return-1;return u;} void Get_ans (int u) {int p=get_mx (U,rt[u],c[u]+dep[u]), if (p==-1) {go[u]=c[u]* (dep[u]-dep[rt[u]]+1) +xp[dep[u]-dep[rt [u]]; Co[u]=c[u]+dep[u]-dep[rt[u]];} else{go[u]=go[p]+c[u]* (Dep[u]-dep[p]) +xp[dep[u]-dep[p]-1];co[u]=co[p];} return;} void Dfs_block (int u,int f) {Get_pre (u,rt[u]); Get_ans (U), if (Rt[f]==rt[u]) s[u]=s[f]+c[u];else s[u]=c[u];for (int i=h[u];i;i=g[i].next) {int v=g[i].to;if (v==f| | Rt[v]!=rt[u]) Continue;dfs_block (v,u);} return;} ll get_cost (int u) {LL ans=go[u]-s[u],la=co[u];u=fa[rt[u]];while (u) {if (La<c[u]) Ans=ans+go[u],la=co[u];else{int p =GET_MX (U,rt[u],la+1+dep[u]); if (p==-1) {ans=ans+ (la+1) * (dep[u]-dep[rt[u]]+1) +xp[dep[u]-dep[rt[u]]];la=la+1+dep[ U]-dep[rt[u]];} else{ans=ans+go[p]+ (la+1) * (Dep[u]-dep[p])+XP[DEP[U]-DEP[P]-1];LA=CO[P];}} Ans-=s[u];u=fa[rt[u]];} return ans;}; int main () {freopen ("increasing.in", "R", stdin); Freopen ("Increasing.out", "w", stdout); int __size__=128<<20; Char *__p__= (char*) malloc (__size__) +__size__;__asm__ ("Movl%0,%%esp\n":: "R" (__p__)); Read (n); Blo=150;memset (C:: Anc,-1,sizeof (C::anc)); xp[0]=0;for (int i=1;i<=n;++i) xp[i]=xp[i-1]+i;for (int i=2;i<=n;++i) {read (f); f++; ADD (f,i); fa[i]=f;} for (int i=1;i<=n;++i) Co[i]=rand ()%n+n,co[i]=-co[i]; S::D FS (1,-1); S::get_pos (+); for (int i=1;i<=n;++i) sz[i]+=w[i],sz[i]-=co[i]; S::build (1,1,n); S::get_splay (1,-1); C::sz[0]=blo; C::get_block (1,0), for (int i=1;i<=n;++i) if (c::rt[i]==i) C::D fs_block (I,fa[i]), read (m), while (m--) {char ch= GetChar (); while (ch< '! ') Ch=getchar (); if (ch== ' M ') {read (u); Read (v); u++; S::get_modify (U,C[U]+V); C::D fs_block (U,fa[u]);} else if (ch== ' S ') printf ("%lld\n", Mx[1]), Else{read (u), u++;p rintf ("%lld\n", C::get_cost (U));}} return 0;}

  

Qaq lis Tree, Lis tree, Qaq 2

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.