Codeforces 374D Inna and Sequence (树状数组+二分OR线段树)

题目链接:http://codeforces.com/group/1EzrFFyOc0/contest/374/problem/D

这两种应该都可以优化,但我懒得想了。。。。。。

树状数组+二分:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include<iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%I64d",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod int(1e9+7)
#define lc (d<<1)
#define rc (d<<1|1)
#define P pair<int,int>
#define pi acos(-1)
int a[1000008],b[1000008],c[1000008],d[1000008],n,m;
int sum(int x)
{
    int s=0;
    while(x>0)
    {
        s+=a[x];
        x-=x&-x;
    }
    return s;
}
void add(int x,int q)
{
    while(x<=n)
    {
        a[x]+=q;
        x+=x&-x;
    }
    return;
}
int main()
{
    cin.tie(0);
    while(si(n)!=EOF)
	{
		si(m);
		REW(a,0);
		REW(c,0);
		int k=0;
		FOR(i,0,m-1)
		{
		    si(b[i]);
		}
		int ttt=n;
		while(ttt--)
        {
            int x;
            si(x);
            if(x<0)
            {
                int zs=0;
                FOR(i,0,m-1)
                {
                    int l=0,r=k;
                    if(sum(k)<b[i]) break;
                    while(l+1<r)
                    {
                        int mid=(l+r)>>1;
                        if(sum(mid)>=b[i])
                        {
                            r=mid;
                        }
                        else
                        {
                            l=mid;
                        }
                    }
                    d[zs++]=r;
                }
                FOR(i,0,zs-1)
                {
                    add(d[i],-1);
                }
            }
            else
            {
                c[++k]=x;
                add(k,1);
            }
        }
        int zz=0;
        FOR(i,1,k)
        {
            if(sum(i)-sum(i-1)==1)
            {
                cout<<c[i];
                zz++;
            }
        }
        if(!zz)
        {
            cout<<"Poor stack!";
        }
        cout<<endl;
	}
    return 0;
}
线段树:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include<iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%I64d",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod int(1e9+7)
#define lc (d<<1)
#define rc (d<<1|1)
#define P pair<int,int>
#define pi acos(-1)
struct as{
int l,r,sum,zz;}tr[1000008<<2];
int n,m,b[1000008];
void push(int d)
{
    tr[d].sum=tr[lc].sum+tr[rc].sum;
    return;
}
void build(int d,int l,int r)
{
    tr[d].l=l,tr[d].r=r,tr[d].zz=-1;
    if(l==r)
    {
        tr[d].sum=0;
        return;
    }
    int mid=(l+r)>>1;
    build(lc,l,mid);
    build(rc,mid+1,r);
    push(d);
    return;
}
void add(int d,int x,int y)
{
    if(tr[d].l==tr[d].r&&tr[d].l==x)
    {
        tr[d].sum=1;
        tr[d].zz=y;
        return;
    }
    int mid=(tr[d].l+tr[d].r)>>1;
    if(x<=mid)
    {
        add(lc,x,y);
    }
    else
    {
        add(rc,x,y);
    }
    push(d);
    return;
}
void add2(int d,int x)
{
    if(tr[d].l==tr[d].r)
    {
        tr[d].sum=0;
        tr[d].zz=-1;
        return;
    }
    if(x<=tr[lc].sum)
    {
        add2(lc,x);
    }
    else
    {
        add2(rc,x-tr[lc].sum);
    }
    push(d);
    return;
}
void query(int d)
{
    if(tr[d].l==tr[d].r&&tr[d].sum)
    {
        cout<<tr[d].zz;
        return;
    }
    if(tr[lc].sum)
    {
        query(lc);
    }
    if(tr[rc].sum)
    {
        query(rc);
    }
    return;
}
int main()
{
    cin.tie(0);
    while(si(n)!=EOF)
	{
		si(m);
		build(1,1,n+5);
		int k=0;
		FOR(i,0,m-1)
		{
		    si(b[i]);
		}
		int ttt=n;
		while(ttt--)
        {
            int x;
            si(x);
            if(x<0)
            {
                FOR(i,0,m-1)
                {
                    int l=0,r=k;
                    if(tr[1].sum<b[i]-i) break;
                    add2(1,b[i]-i);
                }
            }
            else
            {
                add(1,++k,x);
            }
        }
        if(tr[1].sum<=0)
        {
            cout<<"Poor stack!";
        }
        else
        {
            query(1);
        }
        cout<<endl;
	}
    return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值