ACDream 1101 瑶瑶想要玩滑梯 线段树

http://blog.csdn.net/u013368721/article/details/31400053

线段树上的一种dp

//Hello. I‘m Peter.
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
#define peter cout<<"i am peter"<<endl;
#define input freopen("/Users/peteryuanpan/data.txt","r",stdin)
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}

#define N 100010
int n,m,a[N];

#define lch id<<1
#define rch id<<1|1
#define mid ((l+r)>>1)
struct Segment_Tree{
    int lz,len;

    int lv,rv;
    //len from left,len from right
    int lenl,lenr;
    int maxl;

    Segment_Tree(){};
}tree[N<<2];

void pullup(Segment_Tree &treeid,Segment_Tree &treelch,Segment_Tree &treerch){
    //tree[id] is not leaf

    treeid.lv=treelch.lv;
    treeid.lenl=treelch.lenl;
    if(treelch.lenl==treelch.len && treelch.rv<treerch.lv) treeid.lenl=treelch.len+treerch.lenl;

    treeid.rv=treerch.rv;
    treeid.lenr=treerch.lenr;
    if(treerch.lenr==treerch.len && treelch.rv<treerch.lv) treeid.lenr=treelch.lenr+treerch.len;

    treeid.maxl=max(treelch.maxl , treerch.maxl);
    treeid.maxl=max(treeid.maxl , treelch.lenl);
    treeid.maxl=max(treeid.maxl , treerch.lenr);
    if(treelch.rv<treerch.lv) treeid.maxl=max(treeid.maxl , treelch.lenr+treerch.lenl);

}

void plant_tree(int id,int l,int r){
    tree[id].lz=0;
    tree[id].len=r-l+1;

    if(l==r){
        tree[id].lv = tree[id].rv = a[l];
        tree[id].lenl = tree[id].lenr = tree[id].maxl = 1;
        return;
    }

    plant_tree(lch,l,mid);
    plant_tree(rch,mid+1,r);

    pullup(tree[id],tree[lch],tree[rch]);
}

void pushdown(int id){
    if(tree[id].lz){
        tree[lch].lz = tree[id].lz;
        tree[lch].lv = tree[lch].rv = tree[id].lz;
        tree[lch].lenl = tree[lch].lenr = tree[lch].maxl=1;

        tree[rch].lz = tree[id].lz;
        tree[rch].lv = tree[rch].rv = tree[id].lz;
        tree[rch].lenl = tree[rch].lenr = tree[rch].maxl=1;

        tree[id].lz=0;
    }
}

void update(int id,int l,int r,int ql,int qr,int v){
    if(ql==l && qr==r){
        tree[id].lz = v;
        tree[id].lv = tree[id].rv = v;
        tree[id].lenl = tree[id].lenr = tree[id].maxl=1;
        return;
    }

    pushdown(id);

    if(qr<=mid) update(lch,l,mid,ql,qr,v);
    else if(mid<ql) update(rch,mid+1,r,ql,qr,v);
    else update(lch,l,mid,ql,mid,v),update(rch,mid+1,r,mid+1,qr,v);

    pullup(tree[id],tree[lch],tree[rch]);
}

int ans;
void query(int id,int l,int r,int ql,int qr,Segment_Tree &node){
    if(ql==l && qr==r){
        ans=max(ans,tree[id].maxl);
        node=tree[id];
        return;
    }

    pushdown(id);

    if(qr<=mid) query(lch,l,mid,ql,qr,node);
    else if(mid<ql) query(rch,mid+1,r,ql,qr,node);
    else{
        Segment_Tree lson,rson;
        query(lch,l,mid,ql,mid,lson);
        query(rch,mid+1,r,mid+1,qr,rson);

        pullup(node,lson,rson);
        ans=max(ans,node.maxl);
    }

    pullup(tree[id],tree[lch],tree[rch]);
}

int main(){
    //input;
    n=read(),m=read();

    for(int i=1;i<=n;i++){
        a[i]=read();
    }

    plant_tree(1,1,n);

    for(int i=1;i<=m;i++){
        char s[5];
        scanf("%s",s);
        if(s[0]==‘Q‘){
            int l,r;
            l=read(),r=read();

            ans=1;
            Segment_Tree now;
            query(1,1,n,l,r,now);

            printf("%d\n",ans);
        }
        else{
            int l,r,yi;
            l=read(),r=read(),yi=read();

            update(1,1,n,l,r,yi);
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-28 11:40:04

ACDream 1101 瑶瑶想要玩滑梯 线段树的相关文章

ACdream 1101 瑶瑶想要玩滑梯

没想到线段树的基本用法这么长时间没写了还没有忘,1A的感觉还是很爽的. 题目大意: 中文题,点此查看题目. 解题思路: 线段树的区间更新与查询. lazy标记的使用. 当需要返回区间多个值时可以使用引用参数. 下面是代码: #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <math.h> #include <st

ACdream 1101 线段树

题目链接 瑶瑶想要玩滑梯 Time Limit: 10000/5000MS (Java/Others)Memory Limit: 512000/256000KB (Java/Others) SubmitStatisticNext Problem Problem Description 众所周知,瑶瑶(tsyao)是个贪玩的萌妹子,特别喜欢闹腾,恰好今天是一个风和日丽的日子,瑶瑶嚷着让姐姐带她去去公园玩滑梯,可是公园的滑梯比较独特,由单位积木搭成,积木是排成一排搭好,每列有xi个积木,共n列.小明

ACdream 1104 瑶瑶想找回文串(SplayTree + Hash + 二分)

Problem Description 刚学完后缀数组求回文串的瑶瑶(tsyao)想到了另一个问题:如果能够对字符串做一些修改,怎么在每次询问时知道以某个字符为中心的最长回文串长度呢?因为瑶瑶整天只知道LOL,当他知道自己省选成绩的时候就天天在LOL,导致现在的她实在是太弱了,根本解决不了这个问题,于是就来找你帮忙,么么哒~你就帮帮她吗 Input 第一行为一个长度不超过100000字符串s作为初始字符串.第二行一个正整数n,表示操作/询问的个数.接下来n行,每行有如下几种可能出现的操作/询问:

acdream 瑶瑶带你玩激光坦克 (模拟)

瑶瑶带你玩激光坦克 Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 256000/128000KB (Java/Others) Submit Status Problem Description 有一款名为激光坦克的游戏,游戏规则是用一个坦克发出激光来达到一些目的,激光可以通过一些镜子反射. 机智的瑶瑶为了显示自己的智商高于常人,把这个游戏改造了一下,变成了用激光攻击敌人的游戏. 瑶瑶想知道射一次激光最多可以攻击到多少个敌人. PS:

B - 瑶瑶带你玩激光坦克

B - 瑶瑶带你玩激光坦克 Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 256000/128000KB (Java/Others) Submit Status Problem Description 有一款名为激光坦克的游戏,游戏规则是用一个坦克发出激光来达到一些目的,激光可以通过一些镜子反射. 机智的瑶瑶为了显示自己的智商高于常人,把这个游戏改造了一下,变成了用激光攻击敌人的游戏. 瑶瑶想知道射一次激光最多可以攻击到多少个敌人.

ACdream 1099 瑶瑶的第K大

瑶瑶的第K大 Time Limit: 10000/5000MS (Java/Others)Memory Limit: 512000/256000KB (Java/Others) SubmitStatisticNext Problem Problem Description 一天,萌萌的妹子--瑶瑶(tsyao)很无聊,就来找你玩.可是你们都不知道玩什么...尴尬了一阵子,机智的瑶瑶就提议:"这样吧,你说N个整数xi,然后在随意说一个数字k,我能够快速地说出这些数字里面第 k 大的数字."

ACdream 1103 瑶瑶正式成为CEO(树链剖分+费用流)

Problem Description 瑶瑶(tsyao)是某知名货运公司(顺丰)的老板,这个公司很大,货物运输量极大,因此公司修建了许多交通设施,掌控了一个国家的交通运输. 这个国家有n座城市,公司的总部在1号城市. 公司下管辖的有m条道路和n-1段火车线路. 这m条道路和n-1条火车线路都可以用u来表示起点,v来表示终点(数据保证m条道路和n-1条火车线路构成有向无环图). 这n-1段火车道保证从1号城市出发,能够有唯一的一道只包含火车道的线路到达其他n-1座城市. 每条道路和每段火车道都有

第K大 [ACdream 1099] 瑶瑶的第K大

瑶瑶的第K大 Time Limit: 10000/5000MS (Java/Others)Memory Limit: 512000/256000KB (Java/Others) SubmitStatisticNext Problem Problem Description 一天,萌萌的妹子--瑶瑶(tsyao)很无聊,就来找你玩.可是你们都不知道玩什么...尴尬了一阵子,机智的瑶瑶就提议:“这样吧,你说N个整数xi,然后在随意说一个数字k,我能够快速地说出这些数字里面第 k 大的数字.” Inp

OCAC暑期比赛第二场 C题 瑶瑶2356 题解

瑶瑶2356原题链接:http://codeforces.com/problemset/problem/734/B[题目描述]最近瑶瑶在房间里面发现了一个神秘的盒子.她打开盒子,发现里面存放了若干张卡片,每张卡片上面都有一个数字.瑶瑶输了一下,卡片上面的数字只有4种数值:2,3,5,6.并且,她统计了一下,一共有k2张数值为2的卡片,有k3张数值为3的卡片,有k5张数值为5的卡片,有k6张数值为6的卡片.瑶瑶最喜欢的数字是 32 和 256.所以它发现可以用这些卡片拼成数字 32 或者 256.