splay<题目续集>

HDU 3436

Queue-jumpers

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4506    Accepted Submission(s): 1232


Problem Description
Ponyo and Garfield are waiting outside the box-office for their favorite movie. Because queuing is so boring, that they want to play a game to kill the time. The game is called “Queue-jumpers”. Suppose that there are N people numbered from 1 to N stand in a line initially. Each time you should simulate one of the following operations:
1.  Top x :Take person x to the front of the queue
2.  Query x: calculate the current position of person x
3.  Rank x: calculate the current person at position x
Where x is in [1, N].
Ponyo is so clever that she plays the game very well while Garfield has no idea. Garfield is now turning to you for help.
 

 

Input
In the first line there is an integer T, indicates the number of test cases.(T<=50)
In each case, the first line contains two integers N(1<=N<=10^8), Q(1<=Q<=10^5). Then there are Q lines, each line contain an operation as said above. 
 

 

Output
For each test case, output “Case d:“ at first line where d is the case number counted from one, then for each “Query x” operation ,output the current position of person x at a line, for each “Rank x” operation, output the current person at position x at a line.
 

 

Sample Input
3 9 5 Top 1 Rank 3 Top 7 Rank 6 Rank 8 6 2 Top 4 Top 5 7 4 Top 5 Top 2 Query 1 Rank 6
 

 

Sample Output
Case 1: 3 5 8 Case 2: Case 3: 3 6
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>
#define N 200005
#define rl ch[ch[root][1]][0]
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
int root,cnt;
int num[N],key[N],ch[N][2],pre[N],size[N];
int a[N],b[N];
int n,q;
int aa[N];
int a1[N],b1[N];
void newnode(int &x,int fa,int vul){
    x=vul;
    num[x]=size[x]=b[vul]-a[vul]+1;key[x]=a[vul];
    pre[x]=fa;ch[x][0]=ch[x][1]=0;
}
void up(int x){
    size[x]=size[ch[x][0]]+size[ch[x][1]]+num[x];
}
void built(int &x,int l,int r,int fa){
    if(l>r) return ;
    int mid=(l+r)>>1;
    newnode(x,fa,mid);
    built(ch[x][0],l,mid-1,x);
    built(ch[x][1],mid+1,r,x);
    up(x);
}
void rotate(int x,int kind){
    int y=pre[x];
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];pre[y]=x;ch[x][kind]=y;
    up(y);up(x); 
}
void splay(int x,int goal){
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal){
            int kind=ch[pre[x]][0]==x;
            rotate(x,kind);
        }
        else{
            int y=pre[x];
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x){
                rotate(x,!kind);rotate(x,kind);
            }
            else{
                rotate(y,kind);rotate(x,kind);
            }
        }
    }
    if(goal==0) root=x;
    up(x);
}
int ef(int t){
    int l=1;int r=cnt;
    while(l<=r){
        int mid=(l+r)>>1;
        if(t>=a[mid]&&b[mid]>=t){
            return mid;
        }
        else if(t<a[mid]) r=mid-1;
        else l=mid+1;
    }
    return -1;
}
void delet(int x){
    if(ch[x][0]==0){
        pre[ch[x][1]]=0;
        root=ch[x][1];ch[x][1]=0;
        up(root);
    }
    else{
        int t=ch[x][0];
        if(ch[t][1]==0){
            pre[t]=0;root=t;
            pre[ch[x][1]]=t;ch[t][1]=ch[x][1];
            up(root);
            ch[x][1]=ch[x][0]=0;
        }
        else{
            while(ch[t][1]!=0){
                t=ch[t][1];
            }
            splay(t,root);
            pre[t]=0;root=t;
            pre[ch[x][1]]=t;ch[t][1]=ch[x][1];
            up(root);
            ch[x][1]=ch[x][0]=0;
        }
    }
}
void Top(int x){ 
    int y=ef(x);
    splay(y,0);
    if(ch[y][0]==0) return ;
    delet(y);
    size[y]=num[y];
    int temp=root;
    while(ch[temp][0]!=0) temp=ch[temp][0];
    splay(temp,0);
    pre[y]=root;ch[root][0]=y;
    up(root);
}
int Querty(int x){
    int y=ef(x);
    splay(y,0);
    return size[ch[root][0]]+1;
}
int Rank(int x,int t){
    if(t>=size[ch[x][0]]+1&&t<=size[ch[x][0]]+num[x]) return key[x]+(t-size[ch[x][0]]-1);
    else if(t<size[ch[x][0]]+1) return Rank(ch[x][0],t);
    else return Rank(ch[x][1],t-size[ch[x][0]]-num[x]);
}
void init(){
    root=0;
    size[0]=pre[0]=num[0]=0;
    built(root,1,cnt,0);
    up(root);
}
void csh(){
    n=read();q=read();char str[20];
    int t1;cnt=0;int p=0;
    for(int i=1;i<=q;i++){
        scanf(" %s",str);t1=read();
        if(str[0]=='T') {
            a1[i]=1;b1[i]=t1;
            aa[p++]=t1;
        }
        else if(str[0]=='Q'){
            a1[i]=2;b1[i]=t1;
            aa[p++]=t1;
        }
        else a1[i]=3,b1[i]=t1;
    }
    sort(aa,aa+p);
    int t=unique(aa,aa+p)-aa;
    if(t==0){
        a[++cnt]=1;b[cnt]=n;
        return ;
    }
    if(aa[0]!=1){
        a[++cnt]=1;b[cnt]=aa[0]-1;
    }
    for(int i=0;i<t-1;i++){
        a[++cnt]=aa[i];b[cnt]=aa[i];
        if(aa[i+1]-aa[i]>1){
            a[++cnt]=aa[i]+1;b[cnt]=aa[i+1]-1;
        }
    }
    a[++cnt]=aa[t-1];b[cnt]=aa[t-1];
    if(aa[t-1]!=n){
        a[++cnt]=aa[t-1]+1;b[cnt]=n;
    }
}
int main(){
    int T;T=read();
    int Case=0;
    while(T--){
        csh();
        init();
        //cout<<cnt<<endl;
        printf("Case %d:\n",++Case);
        for(int i=1;i<=q;i++){
            if(a1[i]==1){
                Top(b1[i]);
            }
            else if(a1[i]==2){
                printf("%d\n",Querty(b1[i]));
            }
            else printf("%d\n",Rank(root,b1[i]));
        }
    }
    return 0;
}

bzoj 维修序列(最经典的题

/**************************************************************
    Problem: 1500
    User: wang9897
    Language: C++
    Result: Accepted
    Time:4916 ms
    Memory:26684 kb
****************************************************************/
 
#include <bits/stdc++.h>
#define N 500005
#define INF 0x3f3f3f3f
#define rl ch[ch[root][1]][0]
using namespace std;
int root,cnt1,cnt2;
int size[N],pre[N],ch[N][2];
int flag[N],rev[N],l_max[N],r_max[N],sum_max[N],sum[N];
int key[N];
int s[N];
int a[N];
int n,q;
int pos,len,c;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
void newnode(int &x,int fa,int vul){
    if(cnt2) x=s[cnt2--];
    else x=++cnt1;
    flag[x]=rev[x]=ch[x][0]=ch[x][1]=0;
    pre[x]=fa;size[x]=1;
    sum_max[x]=a[vul];
    key[x]=sum[x]=l_max[x]=r_max[x]=a[vul];
}
void update_reverse(int x){
    if(!x) return ;
    swap(ch[x][0],ch[x][1]);
    swap(l_max[x],r_max[x]);
    rev[x]^=1;
}
void update_same(int x,int t){
    if(!x) return ;
    key[x]=t;
    sum[x]=size[x]*t;flag[x]=1;
    l_max[x]=r_max[x]=sum_max[x]=max(size[x]*t,t);
}
void down(int x){
    if(flag[x]){
        update_same(ch[x][0],key[x]);
        update_same(ch[x][1],key[x]);
        flag[x]=0;
    }
    if(rev[x]){
        update_reverse(ch[x][0]);
        update_reverse(ch[x][1]);
        rev[x]=0;
    }
}
void up(int r){
    int lson=ch[r][0],rson=ch[r][1];
    size[r]=size[lson]+size[rson]+1;
    sum[r]=sum[lson]+sum[rson]+key[r];
    l_max[r]=max(l_max[lson],sum[lson]+key[r]+max(0,l_max[rson]));
    r_max[r]=max(r_max[rson],sum[rson]+key[r]+max(0,r_max[lson]));
    sum_max[r]=max(0,r_max[lson])+key[r]+max(0,l_max[rson]);
    sum_max[r]=max(sum_max[r],max(sum_max[lson],sum_max[rson]));
}
void built(int &x,int l,int r,int fa){
    if(l>r) return ;
    int mid=(l+r)>>1;
    newnode(x,fa,mid);
    built(ch[x][0],l,mid-1,x);
    built(ch[x][1],mid+1,r,x);
    up(x);
}
void rotate(int x,int kind){
    int y=pre[x];
    down(y);down(x);
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
    up(y);up(x);
}
void splay(int x,int goal){
    down(x);
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal){
            down(pre[x]);down(x);
            int kind=ch[pre[x]][0]==x;
            rotate(x,kind);
        }
        else{
            int y=pre[x];
            down(pre[y]);down(y);down(x);
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x){
                rotate(x,!kind);
                rotate(x,kind);
            }
            else{
                rotate(y,kind);
                rotate(x,kind);
            }
        }
    }
    if(goal==0) root=x;
    up(x);
}
int find1(int x,int t){
    down(x);
    if(t==size[ch[x][0]]+1) return x;
    else if(t<=size[ch[x][0]]) return find1(ch[x][0],t);
    else return find1(ch[x][1],t-size[ch[x][0]]-1);
    up(x);
}
void inset(){
    pos=read();len=read();
    for(int i=1;i<=len;i++) a[i]=read();
    splay(find1(root,pos+1),0);
    splay(find1(root,pos+2),root);
    built(rl,1,len,ch[root][1]);
    up(ch[root][1]);up(root);
}
void erase(int r){
    if(!r) return ;
    s[++cnt2]=r;
    erase(ch[r][0]);
    erase(ch[r][1]);
}
void delet(){
    pos=read();len=read();
    splay(find1(root,pos),0);
    splay(find1(root,pos+len+1),root);
    erase(rl);
    pre[rl]=0;rl=0;
    up(ch[root][1]);up(root);
}
void Same(){
    pos=read();len=read();c=read();
    splay(find1(root,pos),0);
    splay(find1(root,pos+len+1),root);
    update_same(rl,c);
    up(ch[root][1]);up(root);
}
void Reverse(){
    pos=read();len=read();
    splay(find1(root,pos),0);
    splay(find1(root,pos+len+1),root);
    update_reverse(rl);
    up(ch[root][1]);up(root);   
}
int Sum(){
    pos=read();len=read();
    splay(find1(root,pos),0);
    splay(find1(root,pos+len+1),root);
    return sum[rl];
}
int Max_sum(){
    splay(find1(root,1),0);
    splay(find1(root,size[root]),root);
    return sum_max[rl];
}
void init(){
    n=read();q=read();
    root=cnt1=cnt2=0;
    ch[root][0]=ch[root][1]=pre[root]=size[root]=flag[root]=rev[root]=sum[root]=key[root]=0;
    l_max[root]=r_max[root]=sum_max[root]=-INF;
    for(int i=1;i<=n;i++) a[i]=read();
    newnode(root,0,0);
    newnode(ch[root][1],root,0);
    built(rl,1,n,ch[root][1]);
    up(ch[root][1]);up(root);
}
int main(){
    ios::sync_with_stdio(false);
    init();char str[25];
    while(q--){
        scanf(" %s",str);
        if(strcmp(str,"INSERT")==0) inset();
        else if(strcmp(str,"DELETE")==0) delet();
        else if(strcmp(str,"MAKE-SAME")==0) Same();
        else if(strcmp(str,"REVERSE")==0) Reverse();
        else if(strcmp(str,"GET-SUM")==0) printf("%d\n",Sum());
        else printf("%d\n",Max_sum());
    }
    return 0;
}

bzoj 永无乡

2733: [HNOI2012]永无乡

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 4428  Solved: 2365
[Submit][Status][Discuss]

Description

永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。 
 

Input

输入文件第一行是用空格隔开的两个正整数 n 和 m,分别 表示岛的个数以及一开始存在的桥数。接下来的一行是用空格隔开的 n 个数,依次描述从岛 1 到岛 n 的重要度排名。随后的 m 行每行是用空格隔开的两个正整数 ai 和 bi,表示一开始就存 在一座连接岛 ai 和岛 bi 的桥。后面剩下的部分描述操作,该部分的第一行是一个正整数 q, 表示一共有 q 个操作,接下来的 q 行依次描述每个操作,操作的格式如上所述,以大写字母 Q 或B 开始,后面跟两个不超过 n 的正整数,字母与数字以及两个数字之间用空格隔开。 对于 20%的数据 n≤1000,q≤1000 
 
对于 100%的数据 n≤100000,m≤n,q≤300000 
 

Output

对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-1。 
 

Sample Input

5 1
4 3 2 5 1
1 2
7
Q 3 2
Q 2 1
B 2 3
B 1 5
Q 2 1
Q 2 4
Q 2 3

Sample Output

-1
2
5
1
2
/**************************************************************
    Problem: 2733
    User: wang9897
    Language: C++
    Result: Accepted
    Time:1756 ms
    Memory:5200 kb
****************************************************************/
 
#include <bits/stdc++.h>
#define N 100005
using namespace std;
int ch[N][2],size[N],pre[N],key[N];
int fa[N],root[N],id[N],A[N],a[N];
int cnt,u,v,n,m,q,t1,t2;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
void Treavel(int x)
{
    if(x)
    {
    //  cout<<x<<endl;
        Treavel(ch[x][0]);
        printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
        Treavel(ch[x][1]);
    }
}
void debug(int rp)
{
    printf("root:%d\n",rp);
    Treavel(rp);
}
int find1(int x){
    if(fa[x]!=x) return fa[x]=find1(fa[x]);
    else return x; 
}
int newnode(int fa,int vul){
    cnt++;
    size[cnt]=1;key[cnt]=vul;pre[cnt]=fa;
    ch[cnt][0]=ch[cnt][1]=0;
    return cnt;
}
void up(int x){
    size[x]=size[ch[x][1]]+size[ch[x][0]]+1;
}
void rotate(int x,int kind){
    int y=pre[x];
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
    up(y);up(x);
}
void splay(int x,int goal,int &head){
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal){
            rotate(x,ch[pre[x]][0]==x);
        }
        else{
            int y=pre[x];
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x){
                rotate(x,!kind);rotate(x,kind);
            }
            else{
                rotate(y,kind);rotate(x,kind);
            }
        }
    }
    if(goal==0) head=x;
    up(x);
}
void dfs(int x){
    if(!x) return ;
    A[++A[0]]=x;
    dfs(ch[x][0]);
    dfs(ch[x][1]);
}
void insert(int &x,int t){
    if(x==0){
        x=t;pre[t]=x;
        return ;
    }
    if(key[x]>key[t]) insert(ch[x][0],t);
    else insert(ch[x][1],t);
    up(x);
}
void unoion(){
    scanf("%d %d",&u,&v);
    if(fa[u]==fa[v]) return ;
    if(size[root[fa[u]]]>size[root[fa[v]]]) swap(u,v);
    A[0]=0;;dfs(root[fa[u]]);
    for(int i=1;i<=A[0];i++){
        fa[id[A[i]]]=fa[v];
        size[A[i]]=1;ch[A[i]][0]=ch[A[i]][1]=0;
        insert(root[fa[v]],A[i]);
    }
}
int findK(int x,int t){
    if(t==size[ch[x][0]]+1) return x;
    else if(t<=size[ch[x][0]]) return findK(ch[x][0],t);
    else return findK(ch[x][1],t-size[ch[x][0]]-1);
}
int querty(){
    scanf("%d %d",&u,&v);
    if(size[root[fa[u]]]<v) return -1;
    return id[findK(root[fa[u]],v)];
}
void init(){
    cnt=0;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) {
    scanf("%d",&a[i]);fa[i]=i;}
    for(int i=1;i<=m;i++){
        scanf("%d%d",&u,&v);
        u=find1(u);v=find1(v);
        if(u!=v){
            if(u>v) swap(u,v);
            fa[v]=u;
        }
    }
    for(int i=1;i<=n;i++){
        fa[i]=find1(i);int t=newnode(1,a[i]);
        if(!root[fa[i]]) root[fa[i]]=t;
        else insert(root[fa[i]],t);
        id[t]=i;
    }
//  for(int i=1;i<=n;i++){
//      if(root[i]){
//          debug(root[i]);
//      }
//  }
}
int main(){
    ios::sync_with_stdio(false);
    init();
    scanf("%d",&q);
    char str;
    while(q--){
        scanf(" %c",&str);
        if(str=='B') unoion();
        else printf("%d\n",querty());
    }
    return 0;
}

poj 3481

Double Queue
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 17965   Accepted: 7726

Description

The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provided by IBM Romania, and using modern information technologies. As usual, each client of the bank is identified by a positive integer K and, upon arriving to the bank for some services, he or she receives a positive integer priority P. One of the inventions of the young managers of the bank shocked the software engineer of the serving system. They proposed to break the tradition by sometimes calling the serving desk with the lowest priority instead of that with the highest priority. Thus, the system will receive the following types of request:

0 The system needs to stop serving
K P Add client K to the waiting list with priority P
2 Serve the client with the highest priority and drop him or her from the waiting list
3 Serve the client with the lowest priority and drop him or her from the waiting list

Your task is to help the software engineer of the bank by writing a program to implement the requested serving policy.

Input

Each line of the input contains one of the possible requests; only the last line contains the stop-request (code 0). You may assume that when there is a request to include a new client in the list (code 1), there is no other request in the list of the same client or with the same priority. An identifier K is always less than 106, and a priority P is less than 107. The client may arrive for being served multiple times, and each time may obtain a different priority.

Output

For each request with code 2 or 3, the program has to print, in a separate line of the standard output, the identifier of the served client. If the request arrives when the waiting list is empty, then the program prints zero (0) to the output.

Sample Input

2
1 20 14
1 30 3
2
1 10 99
3
2
2
0

Sample Output

0
20
30
10
0
#include <iostream>
#include <algorithm>
#include <cstdio>
#define rl ch[ch[root][1]][0]
#define lr ch[ch[root][0]][1]
#define N 100005
#define INF 0x3f3f3f3f
using namespace std;
int ch[N][2],size[N],key[N],vul[N],pre[N];
int s[N],cnt1,cnt2,root,n;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
int newnode(int &x,int fa,int vul1,int vul2){
    if(cnt1) x=s[cnt1--];
    else x=++cnt2;
    pre[x]=fa;size[x]=1;key[x]=vul1;vul[x]=vul2;
    ch[x][0]=ch[x][1]=0;
    return x;
}
void up(int x){
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void rotate(int x,int kind){
    int y=pre[x];
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
    up(y);up(x);    
}
void splay(int x,int goal){
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal){
            rotate(x,ch[pre[x]][0]==x);
        }
        else{
            int y=pre[x];
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x){
                rotate(x,!kind);
                rotate(x,kind);
            }
            else{
                rotate(y,kind);
                rotate(x,kind);
            }
        }
    }
    if(goal==0) root=x;
    up(x);
}
void insert(int &x,int t,int fa){
    if(!x){
        x=t;pre[t]=fa;
        return ;
    }
    if(vul[x]>vul[t]) insert(ch[x][0],t,x);
    else insert(ch[x][1],t,x);
    up(x);
}
int find1(int x,int t){
    if(t==size[ch[x][0]]+1) return x;
    else if(t<=size[ch[x][0]]) return find1(ch[x][0],t);
    else return find1(ch[x][1],t-size[ch[x][0]]-1);
}
void delet(int t1){
    if(size[root]<=2){
        printf("0\n");
        return ;
    }
    if(t1==2){
        int tt=find1(root,size[root]-1);
        printf("%d\n",key[tt]);
        splay(find1(root,size[root]-2),0);
        splay(find1(root,size[root]),root);
        s[++cnt1]=rl;rl=0;up(ch[root][1]);up(root);
    }
    else{
        int tt=find1(root,2);
        printf("%d\n",key[tt]);
        splay(find1(root,3),0);
        splay(find1(root,1),root);
        s[++cnt1]=lr;lr=0;up(ch[root][0]);up(root);
    }
}
void init(){
    root=0;cnt1=cnt2=0;
    newnode(root,0,0,-1*INF);
    newnode(ch[root][1],root,0,INF);
}
int main(){
    ios::sync_with_stdio(false);
    init();
    while(scanf("%d",&n)==1){
        if(n==0) break;
        int root1=0;
        if(n==1){
            int t1,t2;
            scanf("%d %d",&t1,&t2);
            int t=newnode(root1,0,t1,t2);
            insert(root,t,0);
        }
        else{
            delet(n);
        }
    }
    return 0;
}

HDU 2475

Box

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3694    Accepted Submission(s): 1085


Problem Description
There are N boxes on the ground, which are labeled by numbers from 1 to N. The boxes are magical, the size of each one can be enlarged or reduced arbitrarily.
Jack can perform the “MOVE x y” operation to the boxes: take out box x; if y = 0, put it on the ground; Otherwise, put it inside box y. All the boxes inside box x remain the same. It is possible that an operation is illegal, that is, if box y is contained (directly or indirectly) by box x, or if y is equal to x.
In the following picture, box 2 and 4 are directly inside box 6, box 3 is directly inside box 4, box 5 is directly inside box 1, box 1 and 6 are on the ground.

The picture below shows the state after Jack performs “MOVE 4 1”:

Then he performs “MOVE 3 0”, the state becomes:

During a sequence of MOVE operations, Jack wants to know the root box of a specified box. The root box of box x is defined as the most outside box which contains box x. In the last picture, the root box of box 5 is box 1, and box 3’s root box is itself.
 

 

Input
Input contains several test cases.
For each test case, the first line has an integer N (1 <= N <= 50000), representing the number of boxes.
Next line has N integers: a1, a2, a3, ... , aN (0 <= ai <= N), describing the initial state of the boxes. If ai is 0, box i is on the ground, it is not contained by any box; Otherwise, box i is directly inside box ai. It is guaranteed that the input state is always correct (No loop exists).
Next line has an integer M (1 <= M <= 100000), representing the number of MOVE operations and queries.
On the next M lines, each line contains a MOVE operation or a query:
1.  MOVE x y, 1 <= x <= N, 0 <= y <= N, which is described above. If an operation is illegal, just ignore it.
2.  QUERY x, 1 <= x <= N, output the root box of box x.
 

 

Output
For each query, output the result on a single line. Use a blank line to separate each test case.
 

 

Sample Input
2 0 1 5 QUERY 1 QUERY 2 MOVE 2 0 MOVE 1 2 QUERY 1 6 0 6 4 6 1 0 4 MOVE 4 1 QUERY 3 MOVE 1 4 QUERY 1
 

 

Sample Output
1 1 2 1 1
#include <bits/stdc++.h>
#define N 100005
using namespace std;
int ch[N][2],pre[N],size[N];
int num[N],p[N],fp[N],cnt,ffp[N],n,m;
vector<int>vec[N];
vector<int>v_;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
void newnode(int &x,int fa,int vul){
    x=vul;
    pre[x]=fa;size[x]=1;
    ch[x][0]=ch[x][1]=0;
}
void up(int x){
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void rotate(int x,int kind){
    int y=pre[x];
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
    up(y);up(x);
}
void splay(int x,int goal){
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal){
            rotate(x,ch[pre[x]][0]==x);
        }
        else{
            int y=pre[x];
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x){
                rotate(x,!kind);
                rotate(x,kind);
            }
            else{
                rotate(y,kind);
                rotate(x,kind);
            }
        }
    }
    up(x);
}
void built(int &x,int l,int r,int fa){
    if(l>r) return ;
    int mid=(l+r)>>1;
    newnode(x,fa,mid);
    built(ch[x][0],l,mid-1,x);
    built(ch[x][1],mid+1,r,x);
    up(x);
}
void dfs(int v,int pre){
    p[++cnt]=v;fp[v]=cnt;num[v]=1;
    for(int i=0;i<vec[v].size();i++){
        if(vec[v][i]!=pre){
            dfs(vec[v][i],v);
            num[v]+=num[vec[v][i]];
        }
    }
    p[++cnt]=-1*v;ffp[v]=cnt;
}
int find1(int x,int t){
    if(t==size[ch[x][0]]+1) return x;
    else if(t<=size[ch[x][0]]) return find1(ch[x][0],t);
    else return find1(ch[x][1],t-size[ch[x][0]]-1);
}
//操作
void move(){
    int t1,t2;scanf("%d%d",&t1,&t2);
    if(t1==t2) return ;
    int temp;
    if(t2!=0){
    splay(fp[t1],0);
    int tt1=p[find1(fp[t1],1)];
    int p1=size[ch[fp[t1]][0]]+1;
    splay(fp[t2],0);
    int tt2=p[find1(fp[t2],1)];
    int p2=size[ch[fp[t2]][0]]+1;
    if(tt1==tt2){
        splay(ffp[t1],0);
        int p3=size[ch[ffp[t1]][0]]+1;
        if(p2>=p1&&p2<=p3) return ;
    }
}
    splay(fp[t1],0);
    if(ch[fp[t1]][0]==0) temp=fp[t1];
    else{
        int root=fp[t1];
        root=find1(root,size[ch[root][0]]);
        splay(root,0);
        splay(ffp[t1],root);
        if(size[ch[ch[root][1]][1]]==0){
            temp=ch[root][1];ch[root][1]=0;
            up(root);
        }
        else{
            int tt=size[ch[root][0]]+3+size[ch[ch[root][1]][0]];
            splay(find1(root,tt),root);
            temp=ch[ch[root][1]][0];ch[ch[root][1]][0]=0;
            up(ch[root][1]);up(root);
        }
    }
    if(t2==0) pre[temp]=0;
    else{        
        int root=fp[t2];
        splay(root,0);
        splay(find1(root,size[ch[root][0]]+2),root);
        ch[ch[root][1]][0]=temp;pre[temp]=ch[root][1];
        up(ch[root][1]);up(root);
    }
}
int querty(){
    int t1;scanf("%d",&t1);
    int root=fp[t1];
    splay(root,0);int x=root;
    while(ch[x][0]) x=ch[x][0];
    return p[x];
}
void init(){
    cnt=0;
    int t;
    for(int i=1;i<=n;i++){
        scanf("%d",&t);
        if(t!=0){
            vec[i].push_back(t);
            vec[t].push_back(i);
        }
        else{
            v_.push_back(i);
        }
    }
    int root=0;
    for(int i=0;i<v_.size();i++){
        dfs(v_[i],-1);
        built(root,cnt-num[v_[i]]*2+1,cnt,0);
    }
}
int main(){
    ios::sync_with_stdio(false);
    int tt=0;
    while(scanf("%d",&n)!=EOF){
        init();char str[105];
        if(tt++) printf("\n");
        scanf("%d",&m);
        while(m--){
            scanf(" %s",str);
            if(str[0]=='Q') printf("%d\n",querty());
            else move();
        }
        for(int i=1;i<=n;i++) vec[i].clear();
        v_.clear();
    }
    return 0;
}

HDU 4441

Queue Sequence

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1809    Accepted Submission(s): 506


Problem Description
There's a queue obeying the first in first out rule. Each time you can either push a number into the queue (+i), or pop a number out from the queue (-i). After a series of operation, you get a sequence (e.g. +1 -1 +2 +4 -2 -4). We call this sequence a queue sequence.

Now you are given a queue sequence and asked to perform several operations:

1. insert p
First you should find the smallest positive number (e.g. i) that does not appear in the current queue sequence, then you are asked to insert the +i at position p (position starts from 0). For -i, insert it into the right most position that result in a valid queue sequence (i.e. when encountered with element -x, the front of the queue should be exactly x).
For example, (+1 -1 +3 +4 -3 -4) would become (+1 +2 -1 +3 +4 -2 -3 -4) after operation 'insert 1'.
2. remove i
Remove +i and -i from the sequence.
For example, (+1 +2 -1 +3 +4 -2 -3 -4) would become (+1 +2 -1 +4 -2 -4) after operation 'remove 3'.
3. query i
Output the sum of elements between +i and -i. For example, the result of query 1, query 2, query 4 in sequence (+1 +2 -1 +4 -2 -4) is 2, 3(obtained by -1 + 4), -2 correspond.
 

 

Input
There are less than 25 test cases. Each case begins with a number indicating the number of operations n (1 ≤ n ≤ 100000). The following n lines with be 'insert p', 'remove i' or 'query i'(0 ≤ p ≤ length (current sequence), 1 ≤ i, i is granted to be in the sequence).
In each case, the sequence is empty initially.
The input is terminated by EOF.
 

 

Output
Before each case, print a line "Case #d:" indicating the id of the test case.
After each operation, output the sum of elements between +i and -i.
 

 

Sample Input
10 insert 0 insert 1 query 1 query 2 insert 2 query 2 remove 1 remove 2 insert 2 query 3 6 insert 0 insert 0 remove 2 query 1 insert 1 query 2
 

 

Sample Output
Case #1: 2 -1 2 0 Case #2: 0 -1
#include <bits/stdc++.h>
#define N 200005
#define ll long long
#define INF 0x3f3f3f3f
#define rl ch[ch[root][1]][0]
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}

int size1[N],size2[N],key[N],ch[N][2],pre[N],v_[N],v__[N];
ll sum[N];
int root,cnt1,cnt2,pos;
int s[N],rt1[N],rt2[N],n;
typedef struct node{
    int vul;
}node;
node d[N<<2];
void built(int root,int l,int r){
    if(l==r){
        d[root].vul=l;
        return ;
    }
    int mid=(l+r)>>1;
    built(root<<1,l,mid);
    built(root<<1|1,mid+1,r);
    d[root].vul=min(d[root<<1].vul,d[root<<1|1].vul);
}
void update(int root,int t,int l,int r,int tt){
    if(l==r){
        if(tt==0) d[root].vul=INF;
        else d[root].vul=l;
        return ;
    }
    int mid=(l+r)>>1;
    if(t<=mid) update(root<<1,t,l,mid,tt);
    else update(root<<1|1,t,mid+1,r,tt);
    d[root].vul=min(d[root<<1].vul,d[root<<1|1].vul);
}
void newnode(int &x,int fa,int vul){
    if(cnt2) x=s[cnt2--];
    else x=++cnt1;
    if(vul<0){
        size1[x]=v_[x]=0;size2[x]=v__[x]=1;
    }
    else{
        size1[x]=v_[x]=1;size2[x]=v__[x]=0;
    }
    pre[x]=fa;sum[x]=key[x]=vul;
    ch[x][0]=ch[x][1]=0;
}
int find1(int x,int t){
    if(t==size1[ch[x][0]]+v_[x]) return x;
    else if(t<size1[ch[x][0]]+v_[x]) return find1(ch[x][0],t);
    else return find1(ch[x][1],t-size1[ch[x][0]]-v_[x]);
}
int find2(int x,int t){
    if(t==size2[ch[x][0]]+v__[x]&&key[x]<0) return x;
    else if(t==size2[ch[x][0]]+v__[x]&&key[x]>0) return find2(ch[x][0],t);
    else if(t<size2[ch[x][0]]+v__[x]) return find2(ch[x][0],t);
    else return find2(ch[x][1],t-size2[ch[x][0]]-v__[x]);
}
int find3(int x,int t){
    if(t==size1[ch[x][0]]+size2[ch[x][0]]+v_[x]+v__[x]) return x;
    else if(t<size1[ch[x][0]]+size2[ch[x][0]]+v_[x]+v__[x]) return find3(ch[x][0],t);
    else return find3(ch[x][1],t-size1[ch[x][0]]-size2[ch[x][0]]-v_[x]-v__[x]);
}
void up(int x){
    sum[x]=(ll)sum[ch[x][0]]+sum[ch[x][1]]+key[x];
    size1[x]=size1[ch[x][0]]+size1[ch[x][1]]+v_[x];
    size2[x]=size2[ch[x][0]]+size2[ch[x][1]]+v__[x];
}
void rotate(int x,int kind){
    int y=pre[x];
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
    up(y);up(x);
}
void splay(int x,int goal){
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal){
            rotate(x,ch[pre[x]][0]==x);
        }
        else{
            int y=pre[x];
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x){
                rotate(x,!kind);rotate(x,kind);
            }
            else{
                rotate(y,kind);rotate(x,kind);
            }
        }
    }
    if(goal==0) root=x;
    up(x);
}
//操作
void insert(){
    scanf("%d",&pos);pos++;
    int t=d[1].vul;update(1,t,1,n,0);
    //cout<<t<<endl;
    if(size1[root]+size2[root]-1==0){
        newnode(ch[root][1],root,t);rt1[t]=ch[root][1];
        newnode(ch[ch[root][1]][1],ch[root][1],-1*t);rt2[t]=ch[ch[root][1]][1];
        up(ch[root][1]);up(root);
    }
    else{
    if(size1[root]+size2[root]==pos){
        splay(find3(root,size1[root]+size2[root]),0);
        newnode(ch[root][1],root,t);rt1[t]=ch[root][1];
        newnode(ch[ch[root][1]][1],ch[root][1],-1*t);rt2[t]=ch[ch[root][1]][1];
        up(ch[root][1]);up(root);
        return ;
    }
    splay(find3(root,pos),0);
    splay(find3(root,pos+1),root);
//    cout<<find3(root,pos)<<" "<<find3(root,pos+1)<<endl;
    newnode(rl,ch[root][1],t);
    rt1[t]=rl;
    up(ch[root][1]);up(root);
    splay(rl,0);
    int tt=size1[ch[root][0]]-1;
    if(tt+1>size2[root]){
        int size=size1[root]+size2[root];
        splay(find3(root,size),root);
        newnode(ch[ch[root][1]][1],ch[root][1],-1*t);
        up(ch[root][1]);up(root);
        rt2[t]=ch[ch[root][1]][1];
    }
    else{
    int ttt=find2(root,tt+1);
    //cout<<tt<<" "<<ttt<<endl;
    splay(ttt,0);
    int size=size1[ch[root][0]]+size2[ch[root][0]];
    //cout<<size<<endl;
    splay(find3(root,size),root);
    newnode(ch[ch[root][0]][1],ch[root][0],-1*t);
    up(ch[root][0]);up(root);
    rt2[t]=ch[ch[root][0]][1];}
    }
//    debug(root);
}
void remove(int x){
    if(!ch[x][0]){
        if(!ch[x][1]) return ;
        pre[ch[x][1]]=0;root=ch[x][1];
        up(root);
    }
    else{
        int y=ch[x][0];
        if(!ch[y][1]){
            pre[y]=0;ch[y][1]=ch[x][1];
            pre[ch[x][1]]=y;root=y;
            up(root);
        }
        else{
            while(ch[y][1]) y=ch[y][1];
            splay(y,x);
            pre[y]=0;ch[y][1]=ch[x][1];
            pre[ch[x][1]]=y;root=y;
            up(root);
        }
    }
}
void delet(){
    scanf("%d",&pos);update(1,pos,1,n,1);
    splay(rt1[pos],0);
    s[++cnt2]=rt1[pos];
    remove(rt1[pos]);
    splay(rt2[pos],0);
    s[++cnt2]=rt2[pos];
    remove(rt2[pos]);
    //debug(root);
}
ll querty(){
    scanf("%d",&pos);
    splay(rt1[pos],0);
    splay(rt2[pos],root);
    return sum[rl];
}
void init(){
    root=cnt1=cnt2=0;
    ch[root][0]=ch[root][1]=size1[root]=size2[root]=pre[root]=v_[root]=v__[root]=0;
    newnode(root,0,1);
    built(1,1,n);
}
int main(){
    ios::sync_with_stdio(false);
    int Case=0;
    while(scanf("%d",&n)!=EOF){
        init();char str[20];
        printf("Case #%d:\n",++Case);
        for(int i=1;i<=n;i++){
            scanf(" %s",str);
            if(str[0]=='i') insert();
            else if(str[0]=='r') delet();
            else printf("%lld\n",querty());
        }
    }
    return 0;
}

HDU 4453

Looploop

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2119    Accepted Submission(s): 717


Problem Description
XXX gets a new toy named Looploop. The toy has N elements arranged in a loop, an arrow pointing to one of the elements, and two preset parameters k1 and k2. Every element has a number on it.



The figure above shows a Looploop of 6 elments. Let's assuming the preset parameter k1 is 3, and k2 is 4.
XXX can do six operations with the toy. 

1: add x 
Starting from the arrow pointed element, add x to the number on the clockwise first k2 elements.



2: reverse
Starting from the arrow pointed element, reverse the first k1 clockwise elements.



3: insert x 
Insert a new element with number x to the right (along clockwise) of the arrow pointed element.



4: delete 
Delete the element the arrow pointed and then move the arrow to the right element.



5: move x 
x can only be 1 or 2. If x = 1 , move the arrow to the left(along the counterclockwise) element, if x = 2 move the arrow to the right element.



6: query
Output the number on the arrow pointed element in one line.



XXX wants to give answers to every query in a serial of operations.
 

 

Input
There are multiple test cases.
For each test case the first line contains N,M,k1,k2(2≤k1<k2≤N≤105, M≤105) indicating the initial number of elements, the total number of operations XXX will do and the two preset parameters of the toy. 
Second line contains N integers ai(-104≤ai≤104) representing the N numbers on the elements in Looploop along clockwise direction. The arrow points to first element in input at the beginning. 
Then m lines follow, each line contains one of the six operations described above.
It is guaranteed that the "x" in the "add","insert" and "move" operations is always integer and its absolute value ≤104. The number of elements will never be less than N during the operations. 
The input ends with a line of 0 0 0 0.
 

 

Output
For each test case, output case number in the first line(formatted as the sample output). Then for each query in the case, output the number on the arrow pointed element in a single line.
 

 

Sample Input
5 1 2 4 3 4 5 6 7 query 5 13 2 4 1 2 3 4 5 move 2 query insert 8 reverse query add 2 query move 1 query move 1 query delete query 0 0 0 0
 

 

Sample Output
Case #1: 3 Case #2: 2 8 10 1 5 1

 

#include <bits/stdc++.h>
#define rl ch[ch[root][1]][0]
#define N 200005
using namespace std;
int ch[N][2],key[N],add[N],flag[N],size[N],pre[N];
int s[N],cnt1,a[N>>1];
int root,cnt2,key_value;
int n,m,k1,k2;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
//准备 
void Treavel(int x)
{
    if(x)
    {
    //    cout<<x<<endl;
        Treavel(ch[x][0]);
        printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
        Treavel(ch[x][1]);
    }
}
void debug(int rp)
{
    printf("root:%d\n",rp);
    Treavel(rp);
}
void newnode(int &x,int fa,int vul){
    if(cnt1) x=s[cnt1--]; 
    else x=++cnt2;
    ch[x][1]=ch[x][0]=0;
    key[x]=vul;add[x]=flag[x]=0;size[x]=1;
    pre[x]=fa;
}
void update_reverse(int x){
    if(!x) return ;
    swap(ch[x][0],ch[x][1]);
    flag[x]^=1;
}
void update_add(int x,int t){
    if(!x) return ;
    key[x]+=t;add[x]+=t;
}
void push(int x){
    if(flag[x]){
        update_reverse(ch[x][0]);
        update_reverse(ch[x][1]);
        flag[x]=0;
    }
    if(add[x]){
        update_add(ch[x][0],add[x]);
        update_add(ch[x][1],add[x]);
        add[x]=0;
    }
}
void up(int x){
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void rotate(int x,int kind){
    int y=pre[x];
    push(y);push(x);
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
    up(y);up(x);
}
void splay(int x,int goal){
    push(x);
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal){
            push(pre[x]);push(x);
            int kind=ch[pre[x]][0]==x;
            rotate(x,kind);
        }
        else{
            int y=pre[x];
            push(pre[y]);push(y);push(x);
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x){
                rotate(x,!kind);
                rotate(x,kind);
            }
            else{
                rotate(y,kind);
                rotate(x,kind);
            }
        }
    }
    if(goal==0) root=x;
    up(x);
}
int find1(int x,int t){
    push(x);
    if(t==size[ch[x][0]]+1) return x;
    else if(t<=size[ch[x][0]]) return find1(ch[x][0],t);
    else return find1(ch[x][1],t-size[ch[x][0]]-1);
    up(x);
}
//操作
void Add(){
    int t;scanf("%d",&t);
    int vul=size[root]-2;
    if(k2>=vul) update_add(root,t);
    else{
        if(key_value-2+k2<=vul){
            splay(find1(root,key_value-1),0);
            splay(find1(root,key_value+k2),root);
            update_add(rl,t);up(ch[root][1]);up(root);
        }
        else{
            int tt=key_value-2+k2-vul;
            splay(find1(root,key_value-1),0);
            splay(find1(root,size[root]),root);
            update_add(rl,t);up(ch[root][1]);up(root);
            //debug(root);
            splay(find1(root,1),root);
            if(size[ch[root][0]]-1==tt){
                update_add(ch[ch[root][0]][1],t);
                up(ch[root][0]);up(root);
            }
            else{
            splay(find1(root,tt+2),ch[root][0]);
            update_add(ch[ch[ch[root][0]][1]][0],t);
            up(ch[ch[root][0]][1]);up(ch[root][0]);up(root);
            }
        }
    }
}
void reverse(){
    int vul=size[root]-2;
    if(k1>=vul) update_reverse(root);
    else{
        if(key_value-2+k1<=vul){
            splay(find1(root,key_value-1),0);
            splay(find1(root,key_value+k1),root);
            update_reverse(rl);up(ch[root][1]);up(root);
        }
        else{
            int ttl=key_value-2+k1-vul;
            int ttr=vul-key_value+2;
            if(ttl==ttr){
                splay(find1(root,key_value-1),0);
                splay(find1(root,size[root]),root);
                update_reverse(rl);
                splay(find1(root,1),root);
                splay(find1(root,ttl+2),ch[root][0]);
                update_reverse(ch[ch[ch[root][0]][1]][0]);
                swap(ch[ch[ch[root][0]][1]][0],rl);
                pre[rl]=ch[root][1];pre[ch[ch[ch[root][0]][1]][0]]=ch[ch[root][0]][1];
                up(ch[root][1]);up(root);
                up(ch[ch[root][0]][1]);up(ch[root][0]);up(root);
            }
            else{
                int t=min(ttl,ttr);
            //    cout<<t<<endl;
                //cout<<key_value-1<<endl;;
                splay(find1(root,key_value-1),0);
                splay(find1(root,key_value+t),root);
            //    debug(root);
                update_reverse(rl);
                //cout<<ttl<<endl;
                splay(find1(root,ttl-t+1),root);
                splay(find1(root,ttl+2),ch[root][0]);
            //    debug(root);
            //    cout<<ch[ch[ch[root][0]][1]][0]<<endl;
                update_reverse(ch[ch[ch[root][0]][1]][0]);
                swap(ch[ch[ch[root][0]][1]][0],rl);
                pre[rl]=ch[root][1];pre[ch[ch[ch[root][0]][1]][0]]=ch[ch[root][0]][1];                
                up(ch[root][1]);up(root);
                up(ch[ch[root][0]][1]);up(ch[root][0]);up(root);
            //    debug(root);
                if(t==ttl){
                    splay(find1(root,key_value+t-1),0);
                    splay(find1(root,size[root]),root);
                    update_reverse(rl);
                    up(ch[root][1]);up(root);                    
                }
                else{
                    splay(find1(root,ttl-t+2),0);
                    splay(find1(root,1),root);
                    update_reverse(ch[ch[root][0]][1]);
                    up(ch[root][0]);up(root);
                }                        
            }
        }
    }
}
void inset(){
    int vul;scanf("%d",&vul);
    splay(find1(root,key_value),0);
    splay(find1(root,key_value+1),root);
    newnode(rl,ch[root][1],vul);
    up(ch[root][1]);up(root);
}
void delet(){
    int t=size[root];
    splay(find1(root,key_value-1),0);
    splay(find1(root,key_value+1),root);
    s[++cnt1]=rl;rl=0;up(ch[root][1]);
    up(root);
    if(key_value==t-1) key_value=2;
}
void move(){
    int t;scanf("%d",&t);
    if(t==1){
        if(key_value==2) key_value=size[root]-1;
        else key_value=key_value-1;
    }
    else{
        if(key_value==size[root]-1) key_value=2;
        else key_value=key_value+1;
    }
}
int querty(){
    return key[find1(root,key_value)];
}
void build(int &x,int l,int r,int fa){
    if(l>r) return ;
    int mid=(l+r)>>1;
    newnode(x,fa,a[mid]);
    build(ch[x][0],l,mid-1,x);
    build(ch[x][1],mid+1,r,x);
    up(x);
}
void init(){
    root=cnt1=cnt2=0;
    key_value=2;
    newnode(root,0,0);
    newnode(ch[root][1],root,0);
    build(rl,1,n,ch[root][1]);
    up(ch[root][1]);up(root);
    //debug(root);
}
int main(){
    ios::sync_with_stdio(false);
    //freopen("test.out","w",stdout);
    int Case=0;
    while(scanf("%d%d%d%d",&n,&m,&k1,&k2)==4){
        if(n==0&&m==0&&k1==0&&k2==0) break;
        printf("Case #%d:\n",++Case);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        init();
        char str[20];
        for(int i=1;i<=m;i++){
            scanf(" %s",str);
            if(str[0]=='a') Add();
            else if(str[0]=='r') reverse();
            else if(str[0]=='i') inset();
            else if(str[0]=='d') delet();
            else if(str[0]=='m') move();
            else printf("%d\n",querty());
        }
    }
    return 0;
}

HDU 3726

Graph and Queries

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4455    Accepted Submission(s): 1036


Problem Description
You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer value assigned to it at the beginning. You're also given a sequence of operations and you need to process them as requested. Here's a list of the possible operations that you might encounter:
1)  Deletes an edge from the graph.
The format is [D X], where X is an integer from 1 to M, indicating the ID of the edge that you should delete. It is guaranteed that no edge will be deleted more than once.
2)  Queries the weight of the vertex with K-th maximum value among all vertexes currently connected with vertex X (including X itself).
The format is [Q X K], where X is an integer from 1 to N, indicating the id of the vertex, and you may assume that K will always fit into a 32-bit signed integer. In case K is illegal, the value for that query will be considered as undefined, and you should return 0 as the answer to that query.
3)  Changes the weight of a vertex.
The format is [C X V], where X is an integer from 1 to N, and V is an integer within the range [-106, 106].

The operations end with one single character, E, which indicates that the current case has ended.
For simplicity, you only need to output one real number - the average answer of all queries.

 

 

Input
There are multiple test cases in the input file. Each case starts with two integers N and M (1 <= N <= 2 * 104, 0 <= M <= 6 * 104), the number of vertexes in the graph. The next N lines describes the initial weight of each vertex (-106 <= weight[i] <= 106). The next part of each test case describes the edges in the graph at the beginning. Vertexes are numbered from 1 to N. The last part of each test case describes the operations to be performed on the graph. It is guaranteed that the number of query operations [Q X K] in each case will be in the range [1, 2 * 105], and there will be no more than 2 * 105 operations that change the values of the vertexes [C X V].

There will be a blank line between two successive cases. A case with N = 0, M = 0 indicates the end of the input file and this case should not be processed by your program.

 

 

Output
For each test case, output one real number – the average answer of all queries, in the format as indicated in the sample output. Please note that the result is rounded to six decimal places.
 

 

Sample Input
3 3 10 20 30 1 2 2 3 1 3 D 3 Q 1 2 Q 2 1 D 2 Q 3 2 C 1 50 Q 1 1 E 3 3 10 20 20 1 2 2 3 1 3 Q 1 1 Q 1 2 Q 1 3 E 0 0
 

 

Sample Output
Case 1: 25.000000 Case 2: 16.666667
#include <bits/stdc++.h>
#define N 20005
#define ll long long
using namespace std;
int pre[N],ch[N][2],size[N],key[N];
int fa[N],root[N],A[N];
int cnt,n,m,q;
bool vis[3*N];
vector<pair<int,int> >v_;
int read() {
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
int find2(int x) {
    if(x!=fa[x]) return fa[x]=find2(fa[x]);
    else return x;
}
int newnode(int fa,int vul) {
    cnt++;
    pre[cnt]=fa;
    size[cnt]=1;
    key[cnt]=vul;
    ch[cnt][0]=ch[cnt][1]=0;
    return cnt;
}
void up(int x) {
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void rotate(int x,int kind) {
    int y=pre[x];
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];
    ch[x][kind]=y;
    pre[y]=x;
    up(y);
    up(x);
}
void splay(int x,int goal,int &head) {
    while(pre[x]!=goal) {
        if(pre[pre[x]]==goal) {
            rotate(x,ch[pre[x]][0]==x);
        } else {
            int y=pre[x];
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x) {
                rotate(x,!kind);
                rotate(x,kind);
            } else {
                rotate(y,kind);
                rotate(x,kind);
            }
        }
    }
    if(goal==0) head=x;
    up(x);
}
void insert(int &x,int t,int fa) {
    if(x==0) {
        x=t;
        pre[t]=fa;
        return ;
    }
    if(key[x]<=key[t]) insert(ch[x][1],t,x);
    else insert(ch[x][0],t,x);
    up(x);
}
int find1(int x,int t) {
    if(t==size[ch[x][0]]+1) return x;
    else if(t<=size[ch[x][0]]) return find1(ch[x][0],t);
    else return find1(ch[x][1],t-size[ch[x][0]]-1);
}
void delet(int x,int &head) {
    if(!ch[x][0]) {
        if(!ch[x][1]) {
            head=0;
            return ;
        }
        pre[ch[x][1]]=0;
        up(ch[x][1]);
        head=ch[x][1];
    } else {
        int y=ch[x][0];
        if(!ch[y][1]) {
            pre[y]=0;
            ch[y][1]=ch[x][1];
            pre[ch[x][1]]=y;
            head=y;
            up(head);
        } else {
            while(ch[y][1]!=0) y=ch[y][1];
            splay(y,x,head);
            pre[y]=0;
            pre[ch[x][1]]=y;
            ch[y][1]=ch[x][1];
            head=y;
            up(head);
        }
    }
}
void dfs(int x) {
    if(!x) return ;
    A[++A[0]]=x;
    dfs(ch[x][0]);
    dfs(ch[x][1]);
}
void unoion(int t) {
    int u=v_[t].first;
    int v=v_[t].second;
    if(fa[u]==fa[v]) return ;
    if(size[root[fa[u]]]>size[root[fa[v]]]) swap(u,v);
    A[0]=0;
    dfs(root[fa[u]]);
    for(int i=1; i<=A[0]; i++) {
        fa[A[i]]=fa[v];
        size[A[i]]=1;
        ch[A[i]][1]=ch[A[i]][0]=0;
        insert(root[fa[v]],A[i],0);
    }
}
void change(int u,int v) {
    splay(u,0,root[fa[u]]);
    delet(u,root[fa[u]]);
    size[u]=1;
    key[u]=v;
    ch[u][1]=ch[u][0]=0;
    insert(root[fa[u]],u,0);
}
int querty(int u,int t) {
    if(size[root[fa[u]]]<t||t<=0) return 0;
//    cout<<size[root[fa[u]]]<<" "<<find1(root[fa[u]],size[root[fa[u]]]-t+1)<<endl;
    return key[find1(root[fa[u]],size[root[fa[u]]]-t+1)];
}
typedef struct node {
    int op;
    int t1,t2;
} node;
node d[20*N];
stack<int>s[N];
double init() {
    cnt=0;
    memset(vis,0,sizeof(vis));
    memset(pre,0,sizeof(pre));
    memset(size,0,sizeof(size));
    memset(root,0,sizeof(root));
    int t1,t2;
    for(int i=1; i<=n; i++) {
        scanf("%d",&t1);
        s[i].push(t1);
        fa[i]=i;
    }
    for(int i=1; i<=m; i++) {
        scanf("%d%d",&t1,&t2);
        v_.push_back(make_pair(t1,t2));
    }
    char ch;
    int cnt1=0,cnt2=0;
    ll ans=0;
    while(1) {
        scanf(" %c",&ch);
        if(ch=='E') break;
        if(ch=='D') {
            scanf("%d",&t1);
            vis[t1]=1;
            d[++cnt1].op=1;
            d[cnt1].t1=t1;
        } else if(ch=='Q') {
            scanf("%d %d",&t1,&t2);
            cnt2++;
            d[++cnt1].op=2;
            d[cnt1].t1=t1;
            d[cnt1].t2=t2;
        } else {
            scanf("%d %d",&t1,&t2);
            s[t1].push(t2);
            d[++cnt1].op=3;
            d[cnt1].t1=t1;
            d[cnt1].t2=t2;
        }
    }
    for(int i=1; i<=m; i++) {
        if(vis[i]) continue;
        t1=find2(v_[i-1].first);
        t2=find2(v_[i-1].second);
        if(t1==t2) continue;
        if(t1>t2) swap(t1,t2);
        fa[t2]=t1;
    }
    for(int i=1; i<=n; i++) {
        int tt=s[i].top();
        s[i].pop();
        fa[i]=find2(i);
        int t=newnode(0,tt);
        if(!root[fa[i]]) root[fa[i]]=t;
        else insert(root[fa[i]],t,0);
    }
    for(int i=cnt1; i>=1; i--) {
        if(d[i].op==1) {
            unoion(d[i].t1-1);
        } else if(d[i].op==2) {
            ans+=querty(d[i].t1,d[i].t2);
        } else {
            int tt=s[d[i].t1].top();
            s[d[i].t1].pop();
            change(d[i].t1,tt);
        }
    }
    //cout<<ans<<endl;
    double ans1=ans*1.0/cnt2;
    return ans1;
}
int main() {
    int Case=0;
    while(scanf("%d %d",&n,&m)==2) {
        if(n==0&&m==0) break;
        //    printf("Case %d: ",++Case);
        printf("Case %d: %.6f\n",++Case,init());
        v_.clear();
    }
    return 0;
}

HDU 4680

About set

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 532    Accepted Submission(s): 147


Problem Description
Today Zhanyl (sister Zhan as you know) receives a task about set operation. Although she is very good at this task, 
but you know she is very lazy so that she wants you to help her write a program to complete this task. Surly
Zhanyl is able to solve this question, but you know, she is just lazy ...
Here is the problem, you are given n numbers, each number i has a value Ai, initially they are in different set. 
Following there are m operations/querys.
The following is 5 possible kinds of oprations/querys:
1 u v: Union the set u belongs to and the set v belongs to.
2 u v: Delete u from its original set and add it to the set v belongs to.
3 u x: change the value of u to x.  1<=x<=109
4 u: query how many numbers you can choose most in set which u belongs to, so no three numbers can form a triangle.
5 u l r: query the gcd of the numbers between [l,r] in the set u belongs to, if there is no number between [l,r],you can suppose the answer is -1.  1<=l<=r<=109
Because Zhanyl is a good person, so she guarantee 1<=u,v<=n above.
You need to tell Zhanyl the answer to each query.
 

 

Input
The first line of the input is a single integer T which is the number of test cases.Then comes the T test cases .
For each test case, the first line contains two integer n and m, n is the number of set initially, m is the number 
of operations/querys.
Following line contains n integers, A1, A2, ... , An, the value of i-th number.
Following m lines, each line is a operation or query.

Note that 1<=n,m<=105, 1<=Ai<=109
 

 

Output
For each case,output "Case #X:" in one line first, X is the case number starting from 1. Following you should output all the querys, each query a line.
 

 

Sample Input
1 5 5 1 2 3 4 5 1 2 4 5 2 1 5 2 1 4 3 2 3 4 2
 

 

Sample Output
Case #1: 2 3
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 300005
#define M 100005
#define ll long long
const int INF=1<<30;
using namespace std;
int Gcd(int x,int y){ 
    if(y==0) return x; 
    else return(Gcd(y,x%y)); 
}
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
int rt[N],_gcd[N],ch[N][2],size[N],pre[N],key[N];
int fa[M];int A[N],id[N];
int root[M];
int cnt,n,q,u,v;
void Treavel(int x)
{
    if(x)
    {
    //    cout<<x<<endl;
        Treavel(ch[x][0]);
        printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
        Treavel(ch[x][1]);
    }
}
void debug(int rp)
{
    printf("root:%d\n",rp);
    Treavel(rp);
}
void newnode(int &x,int fa,int vul){
    cnt++;x=cnt;size[cnt]=1;
    pre[cnt]=fa;
    ch[cnt][0]=ch[cnt][1]=0;
    key[cnt]=_gcd[cnt]=vul;
}
void up(int x){
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
    _gcd[x]=key[x];
    if(ch[x][0]) _gcd[x]=Gcd(_gcd[ch[x][0]],_gcd[x]);
    if(ch[x][1]) _gcd[x]=Gcd(_gcd[ch[x][1]],_gcd[x]);
}
void rotate(int x,int kind){
    int y=pre[x];
    ch[y][!kind]=ch[x][kind];
    pre[ch[x][kind]]=y;
    if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
    pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
    up(y);up(x);
}
void splay(int x,int goal,int &head){
    while(pre[x]!=goal){
        if(pre[pre[x]]==goal){
            int kind=ch[pre[x]][0]==x;
            rotate(x,kind);    
        }
        else{
            int y=pre[x];
            int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x){
                rotate(x,!kind);
                rotate(x,kind);
            }
            else{
                rotate(y,kind);
                rotate(x,kind);
            }
        }
    }
    if(goal==0) head=x;
    up(x);    
}
void inset(int &x,int t){
        int head=x,p=0,val;  
        val=key[t];  
        while(head){  
            p=head;  
            if(val<key[head])  
                head=ch[head][0];  
            else  
                head=ch[head][1];  
        }  
        if(!p) head=t;  
        else {  
            pre[t]=p;ch[p][val>=key[p]]=t;
            splay(t,0,x);
        }  
}
void dfs(int rt){  
    if(ch[rt][0]) dfs(ch[rt][0]);  
    if(key[rt]!=0&&key[rt]!=INF)  
        A[++A[0]]=rt;  
    if(ch[rt][1]) dfs(ch[rt][1]);  
}
void unio(){
    u=read();v=read();
    if(fa[u]==fa[v]) return ;
    if(size[root[fa[u]]]>size[root[fa[v]]]) {
    swap(u,v);}
    A[0]=0;
    dfs(root[fa[u]]);
    for(int i=1;i<=A[0];i++){
        fa[id[A[i]]]=fa[v];
        size[A[i]]=1;_gcd[A[i]]=key[A[i]];
        ch[A[i]][0]=ch[A[i]][1]=0;
        inset(root[fa[v]],A[i]);
        //splay(A[i],root[fa[v]],root[fa[v]]);
    }
   // up(root[fa[v]]);
    //debug(root[fa[v]]);
}
int find2(int x,int k){
    while(x){
    //    cout<<k<<" "<<size[ch[x][0]]<<endl;
        if(k==size[ch[x][0]]+1) return x;
        else if(k<=size[ch[x][0]]) x=ch[x][0];
        else{
            k-=(size[ch[x][0]]+1);x=ch[x][1];
        } 
    }
}
void update(int x,int &head){
    if(!ch[x][0]){
        if(!ch[x][1]) return ;
        pre[ch[x][1]]=0;head=ch[x][1];
        up(ch[x][1]);
    }
    else{
        int y=ch[x][0];
        if(ch[y][1]==0){
            pre[y]=0;head=y;
            pre[ch[x][1]]=y;
            ch[y][1]=ch[x][1];
            up(y);
        }
        else{
            while(ch[y][1]!=0) y=ch[y][1];
            splay(y,x,head);
            pre[y]=0;head=y;
            pre[ch[x][1]]=y;
            ch[y][1]=ch[x][1];
            up(y);
        }
    }
}
void delet(){
    u=read();v=read();
    if(fa[u]==fa[v]) return ;
    //cout<<"sb"<<endl;
    splay(rt[u],0,root[fa[u]]);
    update(rt[u],root[fa[u]]);fa[u]=fa[v];
    //debug(root[fa[u]]);
    size[rt[u]]=1;_gcd[rt[u]]=key[rt[u]];
    ch[rt[u]][0]=ch[rt[u]][1]=0;
    inset(root[fa[v]],rt[u]);
    //splay(rt[u],root[fa[v]],root[fa[v]]);
   // up(root[fa[v]]);
//    debug(rt[v]);
}
void change(){
    u=read();v=read();
    splay(rt[u],0,root[fa[u]]);
    update(rt[u],root[fa[u]]);
    //cout<<"sb"<<endl;
    size[rt[u]]=1;_gcd[rt[u]]=key[rt[u]]=v;
    ch[rt[u]][0]=ch[rt[u]][1]=0;
    inset(root[fa[u]],rt[u]);
    //splay(rt[u],root[fa[u]],root[fa[u]]);
   // up(root[fa[u]]);
//    debug(rt1);
}
int ans2;
int ans1,ans3;
void find3(int x,int t){
    if(!x) return ;
    if(key[x]<=t){
        if(key[x]>ans1) ans3=x,ans1=key[x];
        find3(ch[x][1],t);
    }
    else find3(ch[x][0],t);
}
void find4(int x,int t){
    if(!x) return ;
    if(key[x]>=t){
        if(key[x]<ans1) ans3=x,ans1=key[x];
        find4(ch[x][0],t);
    }
    else find4(ch[x][1],t);
}
int querty_1(){
    u=read();
    if(size[root[fa[u]]]<=4) return size[root[fa[u]]]-2;
    int t1=key[find2(root[fa[u]],2)];int t2=key[find2(root[fa[u]],3)];
    int ans=2;
    while(1){
        ans1=INF;
        find4(root[fa[u]],t1+t2);
        if(ans1==INF) return ans;
        ans++;
        t1=t2;t2=ans1;
    }
    return ans;
}
int querty_2(){
    int l,r;
    u=read();l=read();r=read();
    ans1=-1;
    find3(root[fa[u]],l-1);
    l=ans3;
    ans1=INF+1;
    find4(root[fa[u]],r+1);
    r=ans3;
    splay(l,0,root[fa[u]]);splay(r,root[fa[u]],root[fa[u]]);
    if(!ch[ch[root[fa[u]]][1]][0]) return -1;
    return _gcd[ch[ch[root[fa[u]]][1]][0]];
}
void init(){
    for(int i=1;i<=n;i++) rt[i]=read();
    memset(pre,0,sizeof(pre));
    memset(key,0,sizeof(key));
    memset(ch,0,sizeof(ch));
    memset(size,0,sizeof(size));
    memset(_gcd,0,sizeof(_gcd));
    memset(root,0,sizeof(root));
    cnt=0;
    for(int i=1;i<=n;i++){
        newnode(root[i],0,0);
        newnode(ch[root[i]][1],root[i],INF);
        newnode(ch[ch[root[i]][1]][0],ch[root[i]][1],rt[i]);
        rt[i]=ch[ch[root[i]][1]][0];id[rt[i]]=i;fa[i]=i;
        up(ch[root[i]][1]);up(root[i]);
    }
}
int main(){
//    freopen("test.in","r",stdin);
  //    freopen("test.out","w",stdout);
    int T;scanf("%d",&T);int Case=0;
    while(T--){
        n=read();q=read();
        init();int op;
           printf("Case #%d:\n",++Case);
        while(q--){
            op=read();
            if(op==1) unio();
            else if(op==2) delet();
            else if(op==3) change();
            else if(op==4) printf("%d\n",querty_1());
            else printf("%d\n",querty_2());
        }
    }
    return 0;
}

 

posted @ 2018-01-31 00:44  wang9897  阅读(404)  评论(0编辑  收藏  举报