zoukankan      html  css  js  c++  java
  • BZOJ1251: 序列终结者

    BZOJ1251: 序列终结者

    Description

    网上有许多题,就是给定一个序列,要你支持几种操作:A、B、C、D。

    一看另一道题,又是一个序列 要支持几种操作:D、C、B、A。

    尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……

    这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思。

    这道题目 就叫序列终结者吧。

    【问题描述】

    给定一个长度为N的序列,每个序列的元素是一个整数(废话)。

    要支持以下三种操作:

    1. 将[L,R]这个区间内的所有数加上V。

    2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1。

    3. 求[L,R]这个区间中的最大值。

    最开始所有元素都是0。

    Input

    第一行两个整数N,M。M为操作个数。

    以下M行,每行最多四个整数,依次为K,L,R,V。

    K表示是第几种操作,如果不是第1种操作则K后面只有两个数。

    Output

    对于每个第3种操作,给出正确的回答。

    Sample Input

    4 4
    1 1 3 2
    1 2 4 -1
    2 1 3
    3 2 4

    Sample Output

    2
    【数据范围】
    N<=50000,M<=100000。
    题解Here!
    刚开始学Splay时,我也是一脸懵——区间翻转咋整?
    然后,我先去做了个更难的题目:BZOJ1500: [NOI2005]维修数列
    于是就会做这题了。。。
    区间 [ l , r ] 翻转也就是将 l-1 伸展到根,将 r+1 伸展到 l-1 的右子树,然后对 r+1 的左子树,即 [ l , r ] 这段区间打上一个区间翻转标记flag。
    下次伸展之前把标记下传一下就好了。
    区间加同理。
    附代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define MAXN 50010
    #define MAX 2147483647
    using namespace std;
    int n,m,root,w[MAXN];
    struct node{
    	int son[2];
    	int f,v,s,flag,c;
    }a[MAXN];
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    inline void pushup(int rt){
    	if(!rt)return;
    	a[rt].s=a[a[rt].son[0]].s+a[a[rt].son[1]].s+1;
    	a[rt].v=max(w[rt],max(a[a[rt].son[0]].v,a[a[rt].son[1]].v));
    }
    inline void pushdown(int rt){
    	if(!rt)return;
    	if(a[rt].c){
    		if(a[rt].son[0]){a[a[rt].son[0]].c+=a[rt].c;a[a[rt].son[0]].v+=a[rt].c;w[a[rt].son[0]]+=a[rt].c;}
    		if(a[rt].son[1]){a[a[rt].son[1]].c+=a[rt].c;a[a[rt].son[1]].v+=a[rt].c;w[a[rt].son[1]]+=a[rt].c;}
    		a[rt].c=0;
    	}
    	if(a[rt].flag){
    		a[a[rt].son[0]].flag^=1;a[a[rt].son[1]].flag^=1;a[rt].flag=0;
    		swap(a[rt].son[0],a[rt].son[1]);
    	}
    }
    inline void turn(int rt,int k){
    	int x=a[rt].f,y=a[x].f;
    	pushdown(x);pushdown(rt);
    	a[x].son[!k]=a[rt].son[k];
    	if(a[rt].son[k])a[a[rt].son[k]].f=x;
    	a[rt].f=y;
    	if(y)a[y].son[a[y].son[1]==x]=rt;
    	a[x].f=rt;
    	a[rt].son[k]=x;
    	pushup(x);pushup(rt);
    }
    void splay(int rt,int ancestry){
    	while(a[rt].f!=ancestry){
    		int x=a[rt].f,y=a[x].f;
    		if(y==ancestry)turn(rt,a[x].son[0]==rt);
    		else{
    			int k=a[y].son[0]==x?1:0;
    			if(a[x].son[k]==rt){turn(rt,!k);turn(rt,k);}
    			else{turn(x,k);turn(rt,k);}
    		}
    	}
    	if(ancestry==0)root=rt;
    	pushup(rt);
    }
    int buildtree(int l,int r,int rt){
    	if(l>r)return 0;
    	int mid;
    	if(l==r){
    		a[l].f=rt;
    		a[l].s=1;
    		return l;
    	}
    	mid=l+r>>1;
    	a[mid].son[0]=buildtree(l,mid-1,mid);
    	a[mid].son[1]=buildtree(mid+1,r,mid);
    	a[mid].f=rt;a[mid].s=1;
    	pushup(mid);
    	return mid;
    }
    int kth(int rt,int x){
    	pushdown(rt);
    	int lsons=0;
    	if(a[rt].son[0])lsons=a[a[rt].son[0]].s;
    	if(x==lsons+1)return rt;
    	if(x<=lsons)return kth(a[rt].son[0],x);
    	else return kth(a[rt].son[1],x-lsons-1);
    }
    int split(int rt,int x,int y){
    	int p=kth(rt,x),q=kth(rt,y);
    	splay(p,0);splay(q,p);
    	return a[q].son[0];
    }
    void work(int rt,int x,int y,int k){
    	int p=kth(rt,x),q=kth(rt,y+2),r;
    	splay(p,0);splay(q,p);
    	r=a[q].son[0];
    	a[r].c+=k;a[r].v+=k;w[r]+=k;
    	pushup(q);pushup(p);
    }
    int main(){
    	int f,x,y,k;
    	n=read();m=read();
    	a[0].v=w[0]=w[1]=w[n+2]=-MAX;
    	root=buildtree(1,n+2,0);
    	while(m--){
    		f=read();x=read();y=read();
    		switch(f){
    			case 1:{
    				k=read();
    				work(root,x,y,k);
    				break;
    			}
    			case 2:{
    				k=split(root,x,y+2);
    				a[k].flag^=1;
    				break;
    			}
    			case 3:{
    				k=split(root,x,y+2);
    				printf("%d
    ",a[k].v);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    【C#界面库】关于C#界面库的选择
    asp.net mvc 学习笔记
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(7)- EF增删改查
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(6)- 创建数据库
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(5)- 创建项目结构
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(4)- 漂亮的登录界面
    ASP.NET MVC5 + EF6 + LayUI实战教程,通用后台管理系统框架(3)
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(2)
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(1)
    初学编程:8款最佳Raspberry Pi 操作系统/项目
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9368799.html
Copyright © 2011-2022 走看看