splay<题目续集>
ECharts5.0版本即将上线,来说说我与ECharts的那些事吧!>>>
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
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]. ff8
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 ,key ,ch [2],pre ,size ; int a ,b ; int n,q; int aa ; int a1 ,b1 ; 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); 1ff8 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 ,pre ,ch [2]; int flag ,rev ,l_max ,r_max ,sum_max ,sum ; int key ; int s ; int a ; 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[ ffa 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 MBSubmit: 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 14 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
-12
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 [2],size ,pre ,key ; int fa ,root ,id ,A ,a ; 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 QueueTime 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 |
1 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 [2],size ,key ,vul ,pre ; int s ,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 2000 (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
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 [2],pre ,size ; int num ,p ,fp ,cnt,ffp ,n,m; vector<int>vec ; 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
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 1ff8 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 ,size2 ,key ,ch [2],pre ,v_ ,v__ ; ll sum ; int root,cnt1,cnt2,pos; int s ,rt1 ,rt2 ,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); rt 2000 2[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
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≤10 5, M≤10 5) 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(-10 4≤ai≤10 4) 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 [2],key ,add ,flag ,size ,pre ; int s ,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 1ff8 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
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 [-10 6, 10 6].
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 * 10 4, 0 <= M <= 6 * 10 4), the number of vertexes in the graph. The next N lines describes the initial weight of each vertex (-106 <= weight[i] <= 10 6). 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 * 10 5], and there will be no more than 2 * 10 5 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 ,ch [2],size ,key ; int fa ,root ,A ; 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 ; 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
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 A i, 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<=10 9
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, A 1, A 2, ... , A n, the value of i-th number.
Following m lines, each line is a operation or query.
Note that 1<=n,m<=10 5, 1<=A i<=10 9
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 ,_gcd ,ch [2],size ,pre ,key ; int fa[M];int A ,id ; 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]; 2000 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; }
- <剑指offer>之栈和队列所有题目
- (POJ 1185)炮兵阵地 <状压DP经典题目>
- > <努力的敲打线段树题目中
- android面试题目大全<第一部分>,android基本的UI控件和布局文件知识
- leetcode题目总结<2>
- <C/C++基础>九度OJ题目1000--1049解题练习(二)
- Crossed Ladders<poj2507题目一样>
- android面试题目大全<第三部分>,java高级综合部分
- 题目1554:区间问题 map<int , vector<int> >的使用
- android面试题目大全<第二部分>,java基础部分
- android面试题目大全<完结部分>,android笔试题目集锦
- 三分法(Ternary Search)求解凸(凹)函数的极值问题<题目篇>
- 刘汝佳<算法艺术与信息学竞赛>推荐题目——Poj
- <C/C++基础>九度OJ题目1359--1414解题练习(七)
- 挑战程序设计竞赛里面的部分题目<用java写的>
- 【JAVA】在网上看到的一些题目,在此做一些整理<此贴不定期更新>
- 图论和搜索题目推荐<汇总>
- java程序员面试宝典题目<二>
- 题目<2016/11/30>
- <九度 OJ>题目1019:简单计算器