题解:splay裸题 直接扒了以前poj的代码...ac+1
#include <iostream>
#include <algorithm>
#include <cstdio>
#define N 400005
#define rl ch[ch[root][1]][0]
#define lr ch[ch[root][0]][1]
#define INF 0x3f3f3f3f
#define ll long long
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 size[N],pre[N],ch[N][2];
ll add[N],flag[N],key[N],Min[N];
int a[N],s[N];
int root,cnt1,cnt2,n;
void newnode(int &x,int fa,int vul){
if(cnt2) x=s[cnt2--];
else x=(++cnt1);
size[x]=1;pre[x]=fa;Min[x]=key[x]=vul;
ch[x][0]=ch[x][1]=add[x]=flag[x]=0;
}
void reverse(int x){
if(!x) return ;
swap(ch[x][0],ch[x][1]);
flag[x]^=1;
}
void push(int x){
if(add[x]){
if(ch[x][0]) {
add[ch[x][0]]+=add[x];Min[ch[x][0]]+=add[x];key[ch[x][0]]+=add[x];}
if(ch[x][1]) {
add[ch[x][1]]+=add[x];Min[ch[x][1]]+=add[x];key[ch[x][1]]+=add[x];}
add[x]=0;
}
if(flag[x]){
if(ch[x][0]) reverse(ch[x][0]);
if(ch[x][1]) reverse(ch[x][1]);
flag[x]=0;
}
}
void up(int x){
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
Min[x]=min(key[x],min(Min[ch[x][0]],Min[ch[x][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];pre[y]=x;ch[x][kind]=y;
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]]+1) return find1(ch[x][0],t);
else return find1(ch[x][1],t-size[ch[x][0]]-1);
up(x);
}
void Add(int l,int r,int vul){
splay(find1(root,l),0);splay(find1(root,r+2),root);
add[rl]+=vul;Min[rl]+=vul;key[rl]+=vul;
up(ch[root][1]);up(root);
}
void update(int l,int r){
splay(find1(root,l),0);splay(find1(root,r+2),root);
reverse(rl);
up(ch[root][1]);up(root);
}
void revolve(int l,int r,int t){
int len=t%(r-l+1);
if(!len) return ;
splay(find1(root,r-len+1),0);
splay(find1(root,r+2),root);
up(ch[root][1]);up(root);
int tmp=rl;
rl=0;
splay(find1(root,l),0);
splay(find1(root,l+1),root);
pre[tmp]=ch[root][1];
rl=tmp;
up(ch[root][1]);
up(root);
}
void insert(int t,int p){
splay(find1(root,t+1),0);
splay(find1(root,t+2),root);
newnode(rl,ch[root][1],p);
up(ch[root][1]);up(root);
}
void delet(int t){
splay(find1(root,t),0);
splay(find1(root,t+2),root);
s[++cnt2]=rl;
pre[rl]=0;
rl=0;
up(ch[root][1]);up(root);
}
int min1(int l,int r){
splay(find1(root,l),0);
splay(find1(root,r+2),root);
return Min[rl];
}
void built(int &x,int l,int r,int fa){
if(l>r) return ;
int mid=(l+r)>>1;
newnode(x,fa,a[mid]);
built(ch[x][0],l,mid-1,x);
built(ch[x][1],mid+1,r,x);
up(x);
}
void init(){
for(int i=1;i<=n;i++) a[i]=read();
root=cnt1=cnt2=0;
size[root]=pre[root]=add[root]=flag[root]=ch[root][0]=ch[root][1]=0;
Min[root]=INF;
newnode(root,0,INF);
newnode(ch[root][1],root,INF);
built(rl,1,n,ch[root][1]);
up(ch[root][1]);up(root);
}
int main(){
n=read();
init();
int q=read();char str[102];
int t1,t2,t3;
while(q--){
scanf("%s",str);
if(str[0]=='A'){
t1=read();t2=read();t3=read();
Add(t1,t2,t3);
}
else if(str[0]=='R'&&str[3]=='E'){
t1=read();t2=read();
update(t1,t2);
}
else if(str[0]=='R'){
t1=read();t2=read();t3=read();
revolve(t1,t2,t3);
}
else if(str[0]=='I'){
t1=read();t2=read();
insert(t1,t2);
}
else if(str[0]=='D'){
t1=read();
delet(t1);
}
else if(str[0]=='M'){
t1=read();t2=read();
printf("%d\n",min1(t1,t2));
}
}
return 0;
}
1895: Pku3580 supermemo
Time Limit: 15 Sec Memory Limit: 64 MBSubmit: 643 Solved: 245
[Submit][Status][Discuss]
Description
给出一个初始序列fA1;A2;:::Ang,要求你编写程序支持如下操作: 1. ADDxyD:给子序列fAx:::Ayg的每个元素都加上D。例如对f1,2, 3,4,5g执行"ADD 241" 会得到f1,3,4,5,5g。 2. REVERSExy:将子序列fAx:::Ayg翻转。例如对f1,2,3,4,5g执 行"REVERSE 24"会得到f1,4,3,2,5g。 3. REVOLVExyT:将子序列fAx:::Ayg旋转T个单位。例如, 对f1,2,3,4,5g执行"REVOLVE 242"会得到f1,3,4,2,5g。 4. INSERTxP:在Ax后插入P。例如,对f1,2,3,4,5g执行"INSERT 24"会得到f1,2,4,3,4,5g。 5. DELETEx:删去Ax。例如,对f1,2,3,4,5g执行"DELETE 2"会得 到f1,3,4,5g。 6. MINxy:查询子序列fAx:::Ayg中的最小元素。例如,对于序列f1, 2,3,4,5g,询问"MIN 24"的返回应为2。Input
第一行包含一个整数n,表示初始序列的长度。 以下n行每行包含一个整数,描述初始的序列。 接下来一行包含一个整数m,表示操作的数目。 以下m行每行描述一个操作。Output
对于所有"MIN"操作,输出正确的答案,每行一个。Sample Input
51
2
3
4
5
2
ADD 2 4 1
MIN 4 5
Sample Output
5HINT
输入、输出以及中间运算结果均不会超过32位整数。
对于30%的数据,n;m 6 1000;
对于100%的数据,n;m 6 100000。
转载于:https://wwwblogs/wang9897/p/10336568.html
更多推荐
[BZOJ]1895: Pku3580 supermemo
发布评论