zoukankan      html  css  js  c++  java
  • [BZOJ]1895: Pku3580 supermemo

    题解: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
    ",min1(t1,t2));
    			}
    		}
    	return 0;
    }
    

      

    1895: Pku3580 supermemo

    Time Limit: 15 Sec  Memory Limit: 64 MB
    Submit: 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

    5
    1
    2
    3
    4
    5
    2
    ADD 2 4 1
    MIN 4 5

    Sample Output

    5

    HINT

    输入、输出以及中间运算结果均不会超过32位整数。
    对于30%的数据,n;m 6 1000;
    对于100%的数据,n;m 6 100000。

  • 相关阅读:
    [LeetCode] 493. Reverse Pairs 翻转对
    [LeetCode] Super Washing Machines 超级洗衣机
    [LeetCode] Perfect Number 完美数字
    [LeetCode] 483. Smallest Good Base 最小的好基数
    [LeetCode] Sliding Window Median 滑动窗口中位数
    [LeetCode] Diameter of Binary Tree 二叉树的直径
    [LeetCode] 01 Matrix 零一矩阵
    [LeetCode] Convert BST to Greater Tree 将二叉搜索树BST转为较大树
    [LeetCode] Reverse String II 翻转字符串之二
    [LeetCode] Minimum Time Difference 最短时间差
  • 原文地址:https://www.cnblogs.com/wang9897/p/10336568.html
Copyright © 2011-2022 走看看