CSU 1532: JuQueen(线段树)

1532: JuQueen

Time Limit: 5 Sec  Memory Limit:
512 MB

Submit: 363  Solved: 110

[Submit][Status][Web
Board
]

Description

Input

Output

Sample Input

10 10 5
state 0
groupchange 2 9 7
state 9
groupchange 0 2 10
change 0 -5

Sample Output

0
7
7
3
-3

HINT

题意:  输入 :c  n  q ->给你初始[0,c)去为0的区间,q个操作,n是区间数的上限,即不能超过n

q次操作: state  id     输出下标为id 的数

groupchange   l  r  val    区间【l,r】上的每个数:val>0,加1 val次,如果有一个数==n,停止操作;

val<0,减1 val次,如果有一个数==0,停止操作;输出实际加或减的次数。

change      l   val           同上,改为单点操作

题解:线段树维护区间最大值计最小值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<map>

#define N 4587530
#define Mod 10000007
#define lson l,mid,idx<<1
#define rson mid+1,r,idx<<1|1
#define lc idx<<1
#define rc idx<<1|1
const double EPS = 1e-11;
const double PI = acos ( -1.0 );
const double E = 2.718281828;
typedef long long ll;

const int INF = 100010;

using namespace std;
struct node {
    int Max;
    int Min;
    int se;
} tree[N<<2];

int n,c,q;
int Max,Min;

void push_up(int idx) {
    tree[idx].Max=max(tree[lc].Max,tree[rc].Max);
    tree[idx].Min=min(tree[lc].Min,tree[rc].Min);
}

void build(int l,int r,int idx) {
    tree[idx].se=0;
    if(l==r) {
        tree[idx].Max=0;
        tree[idx].Min=0;
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(idx);
}

void push_down(int idx) {
    if(tree[idx].se) {
        tree[lc].se+=tree[idx].se;
        tree[rc].se+=tree[idx].se;
        tree[lc].Max+=tree[idx].se;
        tree[lc].Min+=tree[idx].se;
        tree[rc].Max+=tree[idx].se;
        tree[rc].Min+=tree[idx].se;
        tree[idx].se=0;
    }
}

void updata(int l,int r,int idx,int x,int y,int val) {
    if(l>=x&&r<=y) {
        tree[idx].Max+=val;
        tree[idx].Min+=val;
        tree[idx].se+=val;
        return;
    }
    push_down(idx);
    int mid=(l+r)>>1;
    if(x<=mid)updata(lson,x,y,val);
    if(y>mid)updata(rson,x,y,val);
    push_up(idx);
}

int query(int l,int r,int idx,int x,int y) {
    if(l>=x&&r<=y) {
        Min=min(tree[idx].Min,Min);
        return  tree[idx].Max;
    }
    push_down(idx);
    int mid=(l+r)>>1;
    int res=0;
    if(x<=mid)res=max(res,query(lson,x,y));
    if(y>mid)res=max(res,query(rson,x,y));
    return res;
}

int main() {
    //freopen("in.txt","r",stdin);
    while(~scanf("%d%d%d",&c,&n,&q)) {
        char s[20];
        int l,r,val;
        build(1,c,1);
        while(q--) {
            scanf("%s",s);
            if(s[0]=='s') {
                scanf("%d",&l);
                printf("%d\n",query(1,c,1,l+1,l+1));
            } else if(s[0]=='g') {
                scanf("%d%d%d",&l,&r,&val);
                Min=INF;
                if(val==0) {
                    printf("0\n");
                    continue;
                }
                int x=query(1,c,1,l+1,r+1);
               // printf("x=%d\n",x);
                if(val>0) {
                    if(n-x>=val) {
                        printf("%d\n",val);
                        updata(1,c,1,l+1,r+1,val);
                    } else {
                        printf("%d\n",n-x);
                        updata(1,c,1,l+1,r+1,n-x);
                    }
                } else {
                    int v=-val;
                    if(Min>=v) {
                        printf("%d\n",val);
                        updata(1,c,1,l+1,r+1,val);
                    } else {
                        printf("%d\n",-1*Min);
                        updata(1,c,1,l+1,r+1,-1*Min);
                    }
                }
            } else {
                scanf("%d%d",&l,&val);
                if(val==0) {
                    printf("0\n");
                    continue;
                }
                Min=INF;
                int x=query(1,c,1,l+1,l+1);
                if(val>0) {
                    if(n-x>=val) {
                        printf("%d\n",val);
                        updata(1,c,1,l+1,l+1,val);
                    } else {
                        printf("%d\n",n-x);
                        updata(1,c,1,l+1,l+1,n-x);
                    }
                } else {
                    int v=-val;
                    if(Min>=v) {
                        printf("%d\n",val);
                        updata(1,c,1,l+1,l+1,val);
                    } else {
                        printf("%d\n",-1*Min);
                        updata(1,c,1,l+1,l+1,-1*Min);
                    }
                }
            }

        }
    }
    return 0;
}
时间: 2024-08-30 00:43:42

CSU 1532: JuQueen(线段树)的相关文章

csu 1809 Parenthesis(线段树)

#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; char s[maxn]; int pre[maxn],Min[maxn<<2]; int n,q,u,v; /* 给一个长度为n(<=1e5)的只有()的匹配字符串,q(<=1e5)次询问 每次询问在原串上交换两个字符,问交换之后是否还是合法子串 如果把(值为1,)值为-1,那么一个区间前缀和不存在<0,并且 最终的和为0,肯定就

CSU 1453: 平衡序列 学会线段树后必做

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1453. 题目:给定一个大小为100000的数组,里面的数字最大也是100000.现在叫你求出一段子序列,使得他们任意两个数差的绝对值都不能超过k 其实这题的关键是数字的范围,不超过100000,这样的话 ,就可以用线段树整段覆盖了.记dp[i]为以这个数字为结尾的,最长的LIS的多少,开始的时候dp[i]=0,用线段树把他覆盖了.每次插入一个数a[i]的时候,都去找[a[i]-k,a[i]+k]

CSU 1110线段树

C - RMQ with Shifts Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit Status Practice CSU 1110 Appoint description:  System Crawler  (2015-03-10) Description In the traditional RMQ (Range Minimum Query) problem, we ha

csu 1555(线段树经典插队模型-根据逆序数还原序列)

1555: Inversion Sequence Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 469  Solved: 167[Submit][Status][Web Board] Description For sequence i1, i2, i3, … , iN, we set aj to be the number of members in the sequence which are prior to j and greater to

CSU 1542 Flipping Parentheses(线段树)

1542: Flipping Parentheses Time Limit: 5 Sec  Memory Limit: 256 MB Submit: 289  Solved: 79 [Submit][Status][Web Board] Description Input Output Sample Input 6 3 ((())) 4 3 1 Sample Output 2 2 1 HINT 题目大意: 给出一个长度为n的已经匹配的括号字符串,然后有Q次操作,每次操作会翻转一个括号,让你翻转最

【线段树】CSU 1414 Query on a Tree

点击打开链接 线段树新功能get,太神奇了啊@[email protected] 先遍历下树,时间戳记录下前后时间 子节点的前后时间都会在父节点的前后时间范围内 用线段树维护区间内深度最大和深度最小 #include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #inc

csu 1551(线段树+DP)

1551: Longest Increasing Subsequence Again Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 267  Solved: 112[Submit][Status][Web Board] Description Give you a numeric sequence. If you can demolish arbitrary amount of numbers, what is the length of the

2016年湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)

原题链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 Description Bobo has a balanced parenthesis sequence P=p1 p2…pn of length n and q questions. The i-th question is whether P remains balanced after pai and pbi  swapped. Note that questions ar

[ACM] SCU 1555 Inversion Sequence (线段树)

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1555 输入5个数 1 2 0 1 0 表示1前面有1个比它大的数,2前面有2个比它大的数-.. 求一个1~n的排列,比如这个就输出3 1 5 2 4 1前面有1个比它大的数,那么1肯定在第二位 2前面有2个比它大的数,那么2肯定排在第四位,有一位被1占了. 3前面有0个比它大的数,那么3肯定在第一位 维护线段树,叶子结点的值为1,维护和.从左到右找第多少个1就可以了. 比如1前面有1个比它大的数