zoukankan      html  css  js  c++  java
  • [Splay]晚练整队

    比赛结束前请不要阅读题解哦

    晚练整队

    Input:exercise.in Output:exercise.out

    题目背景

    Z的体育非常好,因此他非常不愿意参加体育老师组织的晚练。体育老师何等聪明,他利用激将法把小Z引了下来。

    体育老师思考了一段时间,考虑到小Z的体育的确已经很好了,所以他不用晚练。但是体育老师不愿让小Z这么快走,因此让他帮忙整理晚练的队形。

    题目描述

    队形是一个n个人的数列,位于第i个位置上的人都有自己的体魄强度a[i]。

    体育老师有Q个操作:

    1、识别符为“R”,后接两个正整数l,r,表示你要反转区间[l,r]

    举例: 序列为 1 2 3 4 5 6,要反转3 6,得

    1 2 6 5 4 3

    2、识别符为“Q”,后接两个正整数l,r,表示输出第l列到第r列的最大值(数据满足x1≤x2)

    3、识别符为“C”,后接两个正整数x,k,表示把第x个人的体魄强度修改为k

    输入描述

    第一行一个正整数n

    接下来一行共n个正整数表示ai

    接下来一行仅一个正整数Q

    接下来Q行每行一个字符表示识别符,后接操作所需的参数

    输出描述

    若干行,输出所有对Q识别符的答案

    输入样例

    3

    1 2 3

    4

    R 2 3

    Q 1 2

    C 3 8

    Q 2 3

    输出样例

    3

    8

    数据范围

    对于30%的数据,1≤n≤10^2,1≤Q≤10^3

    对于另外40%的数据,没有R操作

    对于100%的数据,1≤n≤10^51≤Q≤10^51≤a≤2*10^7

    分析

    Splay还不会的就先放弃这道题吧

    区间翻转我们只需要像线段树一样打一个懒惰标记(而且因为翻转可以互相抵消所以可以用 rev^=1 计算)

    然后每次要改变有懒标记节点的位置(即旋转或查询)时下传一下即可

    (重点还是要会打Splay啦)

    然后最大值就随便做

    要注意用Splay进行区间操作,可以将(举例区间[l,r]),可以把l-1节点旋至根节点,r+1节点旋至根节点的儿子处,然后r+1节点的左子树就是要处理的区间啦 l-1<subtree<r+1

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int N=1e5+10;
    struct Node {
        int sz,val,mx,f,c[2];
        bool rev;
    }t[N];
    int cnt,rt;
    int a[N],n,q;
    
    void Update(int x) {
        if (!x) return;
        t[x].sz=1+t[t[x].c[0]].sz+t[t[x].c[1]].sz;
        t[x].mx=max(t[x].val,max(t[t[x].c[0]].mx,t[t[x].c[1]].mx));
    }
    
    void Pushdown(int x) {
        if (!x||!t[x].rev) return;
        t[t[x].c[0]].rev^=1;t[t[x].c[1]].rev^=1;
        int p=t[x].c[0];t[x].c[0]=t[x].c[1];t[x].c[1]=p;
        t[x].rev=0;
    }
    
    bool Witch(int x) {return t[t[x].f].c[1]==x;}
    
    void Rotate(int x) {
        Pushdown(x);
        int f=t[x].f,gf=t[f].f,lr=Witch(x);
        t[x].f=gf;if (gf) t[gf].c[Witch(f)]=x; 
        t[f].c[lr]=t[x].c[lr^1];t[t[f].c[lr]].f=f;
        t[x].c[lr^1]=f;t[f].f=x;
        Update(f);Update(x);
    }
    
    void Splay(int x,int goal) {
        for (;t[x].f!=goal;Rotate(x))
            if (t[t[x].f].f!=goal) Rotate(Witch(t[x].f)==Witch(x)?t[x].f:x);
        if (!goal) rt=x;
        Update(x);
    }
    
    void Build(int &x,int l,int r) {
        if (l>r) return;
        if (!x) x=++cnt;
        int mid=l+r>>1;
        t[x].val=a[mid];t[x].sz=1;
        Build(t[x].c[0],l,mid-1);Build(t[x].c[1],mid+1,r);
        t[t[x].c[0]].f=t[t[x].c[1]].f=x;
        Update(x);
    }
    
    int Get(int x,int y) {
        Pushdown(x);
        if (t[t[x].c[0]].sz+1>y) return Get(t[x].c[0],y);
        else {
            if (t[t[x].c[0]].sz+1==y) return x;
            return Get(t[x].c[1],y-t[t[x].c[0]].sz-1);
        }
    }
    
    void Reverse(int l,int r) {
        int x1,x2;
        x1=Get(rt,l);x2=Get(rt,r+2);
        Splay(x1,0);Splay(x2,x1);Update(rt);
        t[t[x2].c[0]].rev^=1;
        Update(t[x2].c[0]);Update(x2);Update(rt);
    }
    
    void Change(int x,int k) {
        int xx=Get(rt,x+1);
        Splay(xx,0);
        t[xx].val=k;
        Update(xx);
    }
    
    int Query(int l,int r) {
        int x1,x2;
        x1=Get(rt,l);x2=Get(rt,r+2);
        Splay(x1,0);Splay(x2,x1);Update(rt);
        return t[t[x2].c[0]].mx;
    }
    
    int main() {
        freopen("exercise10.in","r",stdin);
        freopen("exercise10.out","w",stdout);
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        Build(rt,0,n+1);
        scanf("%d",&q);
        for (int i=1;i<=q;i++) {
            char c[8];int l,r;
            scanf("%s%d%d",c+1,&l,&r);
            if (c[1]=='R') Reverse(l,r);
            if (c[1]=='C') Change(l,r);
            if (c[1]=='Q') printf("%d
    ",Query(l,r));
        }
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    NOIP 2016 提高组 复赛 Day2T1==洛谷2822 组合数问题
    Codevs 1710 == POJ 1190 生日蛋糕 == 洛谷P1731
    [网络流24题] COGS 750 栅格网络流
    [网络流24题] COGS 运输问题1
    狂K 线段树
    Graph coloring技能树
    智能体大赛酱油记
    graph coloring学习记录
    湖北省赛酱油记
    CCCC酱油记
  • 原文地址:https://www.cnblogs.com/mastervan/p/10492524.html
Copyright © 2011-2022 走看看