POJ 2887 Big String 线段树 离线处理

一开始看的时候没什么思路,后来一看卧槽不是简单的离线处理么。反着插入一遍然后直接查询就好了。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r

const int maxq = 2e3 + 10;
const int maxn = 1e6 + 10 + maxq;

int sum[maxn << 2];

void build(int rt,int l,int r) {
    if(l == r) sum[rt] = 1;
    else {
        int mid = (l + r) >> 1;
        build(lson); build(rson);
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
}

void update(int rt,int l,int r,int pos,int tar) {
    if(l == r) sum[rt] = tar;
    else {
        int mid = (l + r) >> 1;
        if(pos <= mid) update(lson,pos,tar);
        else update(rson,pos,tar);
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
}

int query(int rt,int l,int r,int val) {
    if(l == r) return l;
    int mid = (l + r) >> 1;
    if(sum[rt << 1] >= val) return query(lson,val);
    else return query(rson,val - sum[rt << 1]);
}

char str[maxn],str1[maxn],cmd[maxq],val[maxq];
int q,n,len,pos[maxq],rpos[maxn],icnt[maxq];

int main() {
    scanf("%s",str);
    len = strlen(str);
    scanf("%d",&q);
    icnt[0] = len;
    for(int i = 1;i <= q;i++) {
        scanf(" %c",&cmd[i]);
        if(cmd[i] == ‘I‘) {
            scanf(" %c%d",&val[i],&pos[i]);
            icnt[i] = icnt[i - 1] + 1;
        }
        else {
            scanf("%d",&pos[i]);
            icnt[i] = icnt[i - 1];
        }
    }

    n = icnt[q];

    build(1,1,n);

    for(int i = q;i >= 1;i--) if(cmd[i] == ‘I‘) {
        pos[i] = min(pos[i],icnt[i]);
        rpos[i] = query(1,1,n,pos[i]);
        update(1,1,n,rpos[i],0);
        str1[rpos[i]] = val[i];
    }

    for(int i = 1, zcnt = 0;i <= n;i++) {
        if(str1[i] == 0) {
            str1[i] = str[zcnt++];
            //update(1,1,n,i,1);
        }
    }

    for(int i = 1;i <= q;i++) {
        if(cmd[i] == ‘Q‘) {
            int ret = query(1,1,n,pos[i]);
            printf("%c\n",str1[ret]);
        }
        else {
            update(1,1,n,rpos[i],1);
        }
    }
    return 0;
}

  

时间: 2024-11-06 22:11:00

POJ 2887 Big String 线段树 离线处理的相关文章

POJ 1195 2维线段树(树套树实现) 树状数组

1: #include <stdio.h> 2: #include <string.h> 3: #include <stdlib.h> 4: #include <algorithm> 5: #include <iostream> 6: using namespace std; 7:   8: #define LL(a) a<<1 9: #define RR(a) a<<1|1 10: const int MaxL = 10

POJ 3277 City Horizon(线段树+扫描线+离散化)

题目地址:POJ 3277 水题..稍微处理一下然后用求面积并的方法求即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <

POJ 2777 Count Color(线段树)

题目地址:POJ 2777 我去..延迟标记写错了.标记到了叶子节点上....这根本就没延迟嘛...怪不得一直TLE... 这题就是利用二进制来标记颜色的种类.然后利用或|这个符号来统计每个区间不同颜色种数. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h

线段树+离线 hdu5654 xiaoxin and his watermelon candy

传送门:点击打开链接 题意:一个三元组假设满足j=i+1,k=j+1,ai<=aj<=ak,那么就好的.如今告诉你序列.然后Q次询问.每次询问一个区间[l,r],问区间里有多少个三元组满足要求 思路:刚開始看错题目了,原来三元组是连续3个,这作为bc最后一题也太水了把. . . 先一遍预处理.把连续3个满足条件的找出来,放到还有一个数组里排序去重,用这个数组来给三元组哈希.再扫一遍给三元组在之前那个排序好的数组里二分一下得到下标,大概就是哈希一下,用一个数字来表示. 之后的查询.事实上就是.在

gcd(线段树离线处理)——HDU 4630

对应HDU题目:点击打开链接 No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1801    Accepted Submission(s): 770 Problem Description Life is a game,and you lose it,so you suicide. But you can

poj 2182 Lost Cows(线段树经典题)

题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9152   Accepted: 5879 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, th

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

解题报告 题意: 对线段染色,询问线段区间的颜色种数. 思路: 本来直接在线段树上染色,lz标记颜色.每次查询的话访问线段树,求出颜色种数.结果超时了,最坏的情况下,染色可以染到叶子节点. 换成存下区间的颜色种数,这样每次查询就不用找到叶子节点了,用按位或来处理颜色种数. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace

POJ训练计划1177_Picture(扫描线/线段树+离散)

解题报告 题意: 求矩形周长和. 思路: 左扫上扫,扫过了. #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; struct Seg { int lx,rx,ly,ry,h,v; friend bool operator < (Seg a,Seg b) { re

POJ训练计划2828_Buy Tickets(线段树/单点更新)

解题报告 题意: 插队完的顺序. 思路: 倒着处理数据,第i个人占据第j=pos[i]+1个的空位. 线段树维护区间空位信息. #include <iostream> #include <cstdio> #include <cstring> using namespace std; struct node { int x,v; } num[201000]; int sum[1000000],ans[201000]; void cbtree(int rt,int l,in