zoukankan      html  css  js  c++  java
  • CodeForces 916D Jamie and To-do List

    题意

    你需要维护一个任务列表,有 (q) 次操作,每次操作形如以下四种:

    • set a x:设置任务 (a) 的优先级为 (x),如果任务列表中没有 (a) 则加进来。

    • remove a:将任务 (a) 移除列表。

    • query a:求出有多少个任务的优先级比 (a) 的小,如果 (a) 不在列表里输出 (-1)

    • undo d:撤销这次操作之前的 (d) 个操作。

    注意撤销操作可以撤销之前的撤销操作

    ( exttt{Data Range:}1leq qleq 10^5,1leq xleq 10^9,1leqvert avertleq 15)

    题解

    我又是一个不看数据范围的屑 >_<

    为什么这场的 D 比 E 还难写啊

    好久没写可持久化数据结构了,来写个题解复习一下。

    一看到什么撤销操作估计跟可持久化数据结构分不开了。

    看到 query 操作其实可以开一棵可持久化权值线段树来维护一下,然后 set 的话需要一个可持久化数组来维护每个任务的优先级。

    然后按照题意模拟就得了,因为这题的 (xleq 10^9) 所以不写结构体式线段树可以免去建树的空间开销。

    注意一下空间问题即可通过,这里可能要根据数据范围估算一下空间开销。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef int ll;
    typedef long long int li;
    const ll MAXN=2e5+51; 
    map<string,ll>mp;
    ll n,totn,totid,x,id,p,limit=1e9;
    string op,str;
    ll rt[MAXN<<2],rt2[MAXN<<2],sm[MAXN<<6],ls[MAXN<<6],rs[MAXN<<6];
    inline ll read()
    {
        register ll num=0,neg=1;
        register char ch=getchar();
        while(!isdigit(ch)&&ch!='-')
        {
            ch=getchar();
        }
        if(ch=='-')
        {
            neg=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            num=(num<<3)+(num<<1)+(ch-'0');
            ch=getchar();
        }
        return num*neg;
    }
    inline ll getId(string s)
    {
        return mp.find(s)==mp.end()?mp[s]=++totid:mp[s];
    }
    inline void update(ll node)
    {
        sm[node]=sm[ls[node]]+sm[rs[node]];
    }
    inline ll add(ll l,ll r,ll pos,ll val,ll node)
    {
        ll cur=++totn;
        ls[cur]=ls[node],rs[cur]=rs[node];
        if(l==r)
        {
            return sm[cur]=sm[node]+val,cur;
        }
        ll mid=(l+r)>>1;
        if(pos<=mid)
        {
            ls[cur]=add(l,mid,pos,val,ls[node]);
        }
        else
        {
            rs[cur]=add(mid+1,r,pos,val,rs[node]);
        }
        return update(cur),cur;
    }
    inline ll query(ll l,ll r,ll ql,ll qr,ll node)
    {
        if(ql<=l&&qr>=r)
        {
            return sm[node];
        }
        ll mid=(l+r)>>1,res=0;
        res+=ql<=mid?query(l,mid,ql,qr,ls[node]):0;
        res+=qr>mid?query(mid+1,r,ql,qr,rs[node]):0;
        return res;
    }
    int main()
    {
        n=read();
        for(register int i=1;i<=n;i++)
        {
            cin>>op,rt[i]=rt[i-1],rt2[i]=rt2[i-1];
            if(op=="set")
            {
                cin>>str,x=read(),id=getId(str),p=query(1,limit,id,id,rt2[i]);
                p?rt[i]=add(1,limit,p,-1,rt[i]):1;    
                rt[i]=add(1,limit,x,1,rt[i]),rt2[i]=add(1,limit,id,x-p,rt2[i]);
            }
            if(op=="remove")
            {
                cin>>str,id=getId(str),p=query(1,limit,id,id,rt2[i]);
                p?rt[i]=add(1,limit,p,-1,rt[i]):1,rt2[i]=add(1,limit,id,-p,rt2[i]);
            }
            if(op=="undo")
            {
                x=read(),rt[i]=rt[i-x-1],rt2[i]=rt2[i-x-1];
            }
            if(op=="query")
            {
                cin>>str,id=getId(str),p=query(1,limit,id,id,rt2[i]);
                cout<<(p==0||p==1?p-1:query(1,limit,1,p-1,rt[i]))<<endl;
            }
        }
    }
    
  • 相关阅读:
    C/C++多文件之间的变量定义
    PKU POJ 2186 Popular Cows 强连通分量
    重载函数
    ZOJ 2763 Prison Break
    201357 训练赛总结
    hdu 4467 Graph 构造
    201356 训练赛总结
    201353 NEERC 2012, Eastern subregional contest
    2013512 CF 183 总结
    一道动态规划
  • 原文地址:https://www.cnblogs.com/Karry5307/p/13586246.html
Copyright © 2011-2022 走看看