BZOJ 1455 左偏树即可

 1 #include <cstdio>
2 #define LL long long
3 const LL Maxn=1000100;
4 struct Info{LL l,r,v,Dis;}Tree[Maxn];
6 inline void Swap(LL &x,LL &y){LL t=x;x=y;y=t;}
7 LL Get(LL x) {return x==Father[x]?x:Father[x]=Get(Father[x]);}
8 LL Merge(LL u,LL v)
9 {
10     if (u==0 || v==0) return u+v;
11     if (Tree[u].v>Tree[v].v) Swap(u,v);
12     Tree[u].r=Merge(Tree[u].r,v);
13     if (Tree[Tree[u].l].Dis<Tree[Tree[u].r].Dis)
14         Swap(Tree[u].l,Tree[u].r);
15     Tree[u].Dis=Tree[Tree[u].l].Dis+1;
16     return u;
17 }
18 int main()
19 {
20     scanf("%lld",&n);
21     for (LL i=1;i<=n;i++) scanf("%lld",&Tree[i].v),Tree[i].l=Tree[i].r=0;
22     for (LL i=1;i<=n;i++) Father[i]=i;
23     scanf("%lld",&m);
24     for (LL i=1;i<=m;i++)
25     {
26         char ch=getchar();
27         while (ch!='M' && ch!='K') ch=getchar();
28         if (ch=='M')
29         {
30             scanf("%lld%lld",&u,&v);
31             LL fu=Get(u);
32             LL fv=Get(v);
34             LL Tmp=Merge(fu,fv);
35             Father[fu]=Father[fv]=Tmp;
36         }
37         if (ch=='K')
38         {
39             scanf("%lld",&u);
42             printf("%lld\n",Tree[fu].v);
43             LL Tmp=Merge(Tree[fu].l,Tree[fu].r);
44             Father[fu]=Tmp;
45             Father[Tmp]=Tmp;
46         }
47     }
48     return 0;
49 }
BZOJ 1455

BZOJ 1803 用主席树维护Dfs序就可以了

  1 #include <iostream>
2 #include <algorithm>
3 #include <cstring>
4 #include <cstdio>
5 using namespace std;
6 const int Maxn=200010;
7 const int Maxm=4010000;
8 inline void Get_Int(int &x)
9 {
10     x=0; register char ch=getchar(); int f=1;
11     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
12     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f;
13 }
14 inline void Put_Int(int x)
15 {
16     char ch[20]; register int top=0;
17     if (x<0) putchar('-'),x=-x;
18     if (x==0) ch[++top]='0';
19     while (x) ch[++top]=x%10+'0',x/=10;
20     while (top) putchar(ch[top--]); putchar('\n');
21 }
22 struct Node {int Sum; Node * l,* r;};
23 Node Memory[Maxm],*port=Memory,* Root[Maxn],* null;
24 inline void Init() {null=port++;null->Sum=0;null->l=null->r=null;}
25 inline Node* NewNode(Node * last=NULL)
26 {
27     Node * ret=port++;
28     if (last==NULL) {ret->Sum=0; ret->l=ret->r=null;}
29     else {ret->Sum=last->Sum+1; ret->l=last->l; ret->r=last->r;}
30     return ret;
31 }
32 //======================================
34 int cnt,Stamp,u,v,Rank[Maxn],n,C[Maxn],a[Maxn],num;
35 struct Info{int v,id;}Data[Maxn];
36 struct EDGE{int to,next;}edge[Maxn<<1];
37 inline bool Cmp(Info A,Info B) {return A.v<B.v;}
39 void Dfs(int u,int fa)
40 {
41     Dfn[Begin[u]=++Stamp]=u;
43         if (edge[i].to!=fa) Dfs(edge[i].to,u);
44     Dfn[End[u]=++Stamp]=u;
45 }
46 Node * Update(int l,int r,Node *x,int v)
47 {
48     Node * Ret=NewNode(x);
49     if (l==r) return Ret;
50     int mid=(l+r)>>1;
51     if (v<=mid)Ret->l=Update(l,mid,x->l,v); else
52     Ret->r=Update(mid+1,r,x->r,v);
53     return Ret;
54 }
55 void Query(int L,int R,int K)
56 {
57     Node * x=Root[L-1],*y=Root[R];
58     int P=1,Q=num;
59     while (P!=Q)
60     {
61         int mid=(P+Q)>>1;
62         if (P==Q)
63         {
64             printf("%d\n",C[P]);
65             return;
66         }
67         if (y->l->Sum-x->l->Sum<K)
68         {
69             K-=(y->l->Sum-x->l->Sum);
70             x=x->r,y=y->r;
71             P=mid+1;
72         } else
73         {
74             x=x->l,y=y->l;
75             Q=mid;
76         }
77     }
78     printf("%d\n",C[P]);
79     return;
80 }
81 int main()
82 {
83     // freopen("c.in","r",stdin);
84     scanf("%d",&n); Init(); Root[0]=NewNode();
85     for (int i=1;i<=n;i++)
86         scanf("%d",&a[i]),Data[i].v=a[i],Data[i].id=i;
87     sort(Data+1,Data+n+1,Cmp);
88     for (int i=1;i<=n;i++)
89         C[++num]=Data[i].id,Rank[Data[i].id]=num;
91     for (int i=1;i<n;i++)
92     {
93         scanf("%d%d",&u,&v);
95     }
96     Dfs(1,0);
97
98
99     for (int i=1;i<=Stamp;i++)
100         Root[i]=Update(1,num,Root[i-1],Rank[Dfn[i]]);
101     int m,x,k;
102     scanf("%d",&m);
103     for (int i=1;i<=m;i++)
104     {
105         scanf("%d%d",&x,&k); k=k*2;
106         Query(Begin[x],End[x],k);
107     }
108     return 0;
109 }
POJ1803

BZOJ 3364 LCA

 1
2 #include <cstdio>
3 #include <cstring>
4 const int Maxn=400100;
5 struct EDGE{int to,next,w;}edge[Maxn<<1];
8 void Dfs1(int u,int fa)
9 {
10     Size[u]=1;
12     {
13         if (edge[i].to==fa) continue;
14         Dep[edge[i].to]=Dep[u]+1; Fa[edge[i].to]=u;
15         Dis[edge[i].to]=Dis[u]+edge[i].w;
16         Dfs1(edge[i].to,u);
17         Size[u]+=Size[edge[i].to];
18     }
19 }
20 void Dfs2(int u,int fa,int chain)
21 {
22     int k=0; Top[u]=chain;
24     {
25         if (edge[i].to==fa) continue;
26         if (Size[edge[i].to]>Size[k] || k==0) k=edge[i].to;
27     }
28     if (k==0) return;
29     Dfs2(k,u,chain);
31         if (edge[i].to!=fa && edge[i].to!=k)
32             Dfs2(edge[i].to,u,edge[i].to);
33 }
34 int Lca(int u,int v)
35 {
36     while (true)
37     {
38         if (Top[u]==Top[v]) return Dep[u]>Dep[v]?v:u;
39         if (Dep[Top[u]]>Dep[Top[v]]) u=Fa[Top[u]]; else v=Fa[Top[v]];
40     }
41 }
42 int main()
43 {
44     // freopen("c.in","r",stdin);
45     while (scanf("%d%d",&n,&m)!=EOF)
46     {
48         char Str[5];
49         for (int i=1;i<=m;i++)
50         {
51             scanf("%d%d%d%s",&u,&v,&w,Str);
53         }
54         Dep[1]=1; Fa[1]=1; Dis[1]=0;
55         Dfs1(1,0);
56         Dfs2(1,0,1);
57         scanf("%d",&Q);
58         for (int i=1;i<=Q;i++)
59         {
60             scanf("%d%d",&u,&v);
61             printf("%d\n",Dis[u]+Dis[v]-2*Dis[Lca(u,v)]);
62         }
63     }
64     return 0;
65 }

 1 #include <cstdio>
2 #include <cstring>
3 const int Maxn=400100;
4 struct EDGE{int to,next,w;}edge[Maxn<<1];
7 inline void Swap(int &x,int &y){int t=x;x=y;y=t;}
8 void Dfs(int u,int fa)
9 {
11     {
12         if (edge[i].to==fa) continue;
13         Dep[edge[i].to]=Dep[u]+1; Fa[edge[i].to][0]=u;
14         Dis[edge[i].to]=Dis[u]+edge[i].w;
15         Dfs(edge[i].to,u);
16     }
17 }
18 inline void Init()
19 {
20     for (int i=1;i<=18;i++)
21         for (int j=1;j<=n;j++) Fa[j][i]=Fa[Fa[j][i-1]][i-1];
22 }
23 inline int Lca(int u,int v)
24 {
25     if (Dep[u]>Dep[v]) Swap(u,v);
26     int Len=Dep[v]-Dep[u];
27     for (int i=0;i<=18;i++)
28         if (Len&(1<<i)) v=Fa[v][i];
29     for (int i=18;i>=0;i--)
30         if (Fa[u][i]!=Fa[v][i]) u=Fa[u][i],v=Fa[v][i];
31     if (u!=v) return Fa[u][0];
32     return u;
33 }
34 int main()
35 {
36     // freopen("c.in","r",stdin);
37     while (scanf("%d%d",&n,&m)!=EOF)
38     {
40         char Str[5];
41         for (int i=1;i<=m;i++)
42         {
43             scanf("%d%d%d%s",&u,&v,&w,Str);
45         }
46         Dep[1]=1; Fa[1][0]=1; Dis[1]=0;
47         Dfs(1,0); Init();
48         scanf("%d",&Q);
49         for (int i=1;i<=Q;i++)
50         {
51             scanf("%d%d",&u,&v);
52             printf("%d\n",Dis[u]+Dis[v]-2*Dis[Lca(u,v)]);
53         }
54     }
55     return 0;

BZOJ 1699 RMQ

 1 #include <cstdio>
2 #include <cmath>
3 const int Maxn=50100;
4 int FMax[Maxn][20],FMin[Maxn][20],n,q,l,r,x;
5 inline int Min(int x,int y) {return x>y?y:x;}
6 inline int Max(int x,int y) {return x>y?x:y;}
7 inline void Init()
8 {
9     for (int i=1;i<=18;i++)
10         for (int j=1;j+(1<<(i-1))<=n;j++)
11         {
12             FMax[j][i]=Max(FMax[j+(1<<(i-1))][i-1],FMax[j][i-1]);
13             FMin[j][i]=Min(FMin[j+(1<<(i-1))][i-1],FMin[j][i-1]);
14         }
15 }
16 inline int Query(int l,int r)
17 {
18     int Len=(int)log2(r-l+1);
19
20     return Max(FMax[l][Len],FMax[r-(1<<Len)+1][Len])-Min(FMin[l][Len],FMin[r-(1<<Len)+1][Len]);
21 }
22 int main()
23 {
24     // freopen("c.in","r",stdin);
25     scanf("%d%d",&n,&q);
26     for (int i=1;i<=n;i++) scanf("%d",&x),FMax[i][0]=x,FMin[i][0]=x;
27     Init();
28     for (int i=1;i<=q;i++)
29     {
30         scanf("%d%d",&l,&r);
31         printf("%d\n",Query(l,r));
32     }
33     return 0;
34 }
RMQ