Codeforces Round #220 (Div. 2)D. Inna and Sequence 树状数组+二分

题目链接:D. Inna and Sequence

题意:三种操作,1往序列后面加个1,0往序列后面加个0,-1,把给定位置上的数删除。

题解:用树状数组保存的数没被删的个数,每次二分找到位置,然后用数组标记这里被删除。

#include<bits/stdc++.h>
#include<set>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
typedef unsigned long long ull;
const int mod=1e9+9;
const int inf=0x3f3f3f3f;
const int maxn=1e6+5;
const int root=1e6+7;
using namespace std;
ll t,n,m,k,len;
int tot,ed;
int a[maxn],b[maxn],v[maxn];
int p[maxn];
vector<int>st;
int  lowbit(int x)
{
    return x&(-x);
}
void add(int x,int y)
{
    for(int i=x;i<maxn;i+=lowbit(i))
    {
        b[i]+=y;
    }
}
int get_sum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=b[x];
        x-=lowbit(x);
    }
    return ans;
}
int sec(int x)
{
    int l=1,r=ed;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(get_sum(mid)>=x)r=mid-1;
        else l=mid+1;
    }
    return l;
}
void view()
{
     for(int i=1;i<=ed;i++)
    {
        if(!v[i])cout<<a[i];
    }
    cout<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        cin>>p[i];
    }
    int op;
    while(n--)
    {
        cin>>op;
        if(op==1)
        {
            ++tot;
            a[++ed]=1;
            add(ed,1);
        }
        else if(op==0)
        {
            ++tot;
            ++ed;
            add(ed,1);
        }
        else
        {
            if(tot<=0)continue;
            int pp=lower_bound(p,p+m,tot)-p;
            if(p[pp]==tot)pp++;
            for(int i=0;i<pp;i++)
            {
                int l=sec(p[i]);
                st.pb(l);
                tot--;
                v[l]=true;
            }
            for(int i=0;i<st.size();i++)
            {
                add(st[i],-1);
            }
            st.clear();
        }
     //   view();
    }
    if(tot>0)
    {
        view();
    }
    else{
        cout<<"Poor stack!"<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lhclqslove/p/8424180.html

时间: 2024-08-18 06:46:05

Codeforces Round #220 (Div. 2)D. Inna and Sequence 树状数组+二分的相关文章

Codeforces Round #216 (Div. 2) E. Valera and Queries 树状数组 离线处理

题意:n个线段[Li, Ri], m次询问, 每次询问由cnt个点组成,输出包含cnt个点中任意一个点的线段的总数. 由于是无修改的,所以我们首先应该往离线上想, 不过我是没想出来. 首先反着做,先求不包含这个cnt个点的线段的总数, 那么不包含这些点的线段必然在cnt个点之间(这里需要再加两个点一个是0, 一个是MAX), 我们可以把所有线段按Ri 分类, 然后按右端点遍历,对于当前的线段可以在Li 处+1, 然后对于每一次询问中两个点(x, y)之间线段的个数, 只需要查询 左端点大于等于x

Codefroces 374 B Inna and Sequence (树状数组 || 线段树)

Inna and Sequence 题意:先给你一个n,一个m, 然后接下来输入m个数,表示每次拳击会掉出数的位置,然后输入m个数,每次输入1或0在数列的末尾加上1或0,如果输入-1,相应m序列的数的位置就会掉出来并且后面的数会向前补位(每次删除操作可以看作是同时进行的,只有删除结束之后才会进行补位),最后输出这个数列的剩下结果,如果数列为空就输出"Poor stack!". 题解:一开始想到的思路还是和上次CF889F想到的一样,在删除的位置标记一下,然后每次2分去查找在前面删除操作

Educational Codeforces Round 8(E. Zbazi in Zeydabad(树状数组优化))

题目链接:点击打开链接 题意:一个n*m矩阵, 里面的格子除了'z'就是'.',问有多少个z形图案. 思路:因为n和m很大, 即使n^3复杂度也会超时.  如果按照最朴素的方法, 我们可以处理一下前缀和, 处理出一个格子向左l[i][j].向右r[i][j].斜向左下lr[i][j]连着的z到哪里为止, 这样我们用n^2复杂度枚举每一个格子作为z形图案的右上角,取min(l[i][j], lr[i][j]), 就可以立刻知道这个z形的最左下角到哪里, 然后在这个对角线上扫一遍, 看看向右最远是不

1076E/Educational Codeforces Round 54-E. Vasya and a Tree&lt;&lt;dfs序 树状数组

题意 给定一棵树,初始每个节点权值为零,q次更改,每次修改将以v为顶点的深度为d的子树全部加上x,最后输出所有节点的权重. 思路 题目只要求每个点最后的值,那么经过观察,发现一个点最后的权值大小只与他的父节点的更新有关,那么我们就只需要考虑他的父节点到他这条链上的情况,把这条链拿出来成为线段,然后维护后缀和就能得到此点上的权值.每个节点的贡献为给$[h,h+d]$增加$x$,所以维护时,只要在$h+d$点上加上$x$即可. 但是问题考察的是一棵树,我们就需要动态来完成这条链,我们采用dfs序去扫

Codeforces Round #426 (Div. 2) D. The Bakery(线段树维护dp)

题目链接: Codeforces Round #426 (Div. 2) D. The Bakery 题意: 给你n个数,划分为k段,每段的价值为这一段不同的数的个数,问如何划分,使得价值最大. 题解: 考虑dp[i][j]表示划分为前j个数划分为i段的最大价值,那么这就是一个n*n*k的dp, 考虑转移方程dp[i][j]=max{dp[i][k]+val[k+1][j]},我们用线段树去维护这个max,线段树上每个节点维护的值是dp[i][k]+val[k+1][j],对于每加进来的一个数a

Codeforces Round #424 (Div. 2) E. Cards Sorting(线段树)

题目链接:Codeforces Round #424 (Div. 2) E. Cards Sorting 题意: 将n个数放进一个队列,每次检查队首,看看是不是队列中最小的数,如果是就扔掉,如果不是就放到队尾. 这样直到队列为空,为需要操作多少次. 题解: 考虑用两个指针模拟,最开始now指针指向第一个数,然后nxt指针指向下一个将要被删除的数. 然后我们要算出这里需要移动多少步,然后删掉这个数,一直重复操作,直到将全部的数删完. nxt指针可以用set来维护,now指针可以用并查集来维护. 计

Codeforces Round #603 (Div. 2) E. Editor(线段树)

链接: https://codeforces.com/contest/1263/problem/E 题意: The development of a text editor is a hard problem. You need to implement an extra module for brackets coloring in text. Your editor consists of a line with infinite length and cursor, which point

Codeforces Round #220 (Div. 2) D 树状数组 &amp;&amp; 二分

/*题目*/ 题意:给了n,m,然后一个包含m个数的数组nnum,数组默认从小到大排序,然后是 n个操作,输入一个数x,若x为0,把0加到这个字符串的末尾,若x为1,把1加到这个字符串的末尾,若x为-1,那么把字符串里的 下标 与 nnum数组里的元素相等的  给删除,字符串一开始是空的,问你最后字符串里有什么,若为空 就输出 POOR STACK 这题目看这操作一般都很容易联想到线段树,树状数组,一开始我建了个树状数组,但是超时了,毕竟操作很多,而且 在删除操作里,若nnum数组很大,等同于1

Codeforces Round #244 (Div. 2) B. Prison Transfer 线段树rmq

B. Prison Transfer Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/427/B Description The prison of your city has n prisoners. As the prison can't accommodate all of them, the city mayor has decided to transfer c