51nod 1207

原创 2015年11月18日 10:26:59

#include <bits/stdc++.h>
#define rep(ii,a,b) for (int ii=(a);ii<=(b);ii++)
#define rek(ii,a,b) for (int ii=(a);ii>=(b);ii--)
using namespace std;
const int maxn=100010;
int n,m;
int len;
int fa[maxn],c[maxn][2],siz[maxn],lx[maxn],rx[maxn],maxs[maxn],sta[maxn];
int root;
void updata(int x){
    if (x==0) return;
    siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;
    maxs[x]=rx[x]-lx[x]+1;
    if (c[x][0]) maxs[x]=max(maxs[x],maxs[c[x][0]]);
    if (c[x][1]) maxs[x]=max(maxs[x],maxs[c[x][1]]);
}
void link(int x,int y,int der){
    if (x!=0) c[x][der]=y;
    if (y!=0) fa[y]=x;
    updata(x);
}
void cut(int x,int y,int der){
    updata(x);
    if (x!=0) c[x][der]=0;
    if (y!=0) fa[y]=0;
    updata(x);
}
void rorate(int x){
    if (fa[x]==0) return ;
    int t=fa[x],t1=fa[fa[x]];
    int p=(c[t][1]==x);
    int p1=(c[fa[t]][1]==t);

    link(t1,x,p1);
    link(t,c[x][!p],p);
    link(x,t,!p);

    updata(t);
}
void splay(int x,int y){
    while (fa[x]!=y){
      if (fa[fa[x]]!=y){
         if ((c[fa[x]][0]==x)^(c[fa[fa[x]]][0]==fa[x])){
               rorate(x);
          }else{
             rorate(fa[x]);
         }
    }
      rorate(x);
    }
    updata(x);
    if (y==0) root=x; else updata(y);
}
int getrank(int x,int k){
    int i=x;
    int j=k;
    while (true){
        if (j==siz[c[i][0]]+1) return i;
        if (siz[c[i][0]]+1<j) {
            j-=(siz[c[i][0]]+1);
            i=c[i][1];
        } else{
            i=c[i][0];
        }
    }
}
void del(int now){
     splay(now,0);
     int i=c[now][0];
     while (c[i][1]) i=c[i][1];
     int j=c[now][1];
     while (c[j][0]) j=c[j][0];
     splay(i,0);
     splay(j,i);
     c[j][0]=0;
     updata(j);
     updata(i);
}
int getnext(int now){
    splay(now,0);
    int i=c[now][1];
    while (c[i][0]) i=c[i][0];
    return i;
}
int getlast(int now){
    splay(now,0);
    int i=c[now][0];
    while (c[i][1]) i=c[i][1];
    return i;
}
int solve(int x){
    int i=root;
    if (maxs[i]<x) return -1;
    while (i){
        if (maxs[c[i][0]]>=x && c[i][0]!=0) i=c[i][0];else {
                if (rx[i]-lx[i]+1>=x && rx[i]<=n && lx[i]>=0)
                        {
                            int ans=lx[i];
                            splay(i,0);
                            lx[i]+=x;
                            updata(i);
                            if (lx[i]>rx[i]) del(i);
                            return ans;
                        }
                i=c[i][1];
        }
    }
}
bool pd_lr(int l,int r,int ll,int rr){
    if (l>ll) {swap(l,ll);swap(r,rr);}
    if (r==ll-1) return true;
    if (r<ll) return false;
    if (l>rr) return false;
    return true;
}
void cover(int l,int r){
    int i=root,j,ans=0;
    while (i){
        if (rx[i]>=l)
        if ((ans==0)||(rx[ans]>rx[i])) ans=i;
        if (rx[i]>=l) i=c[i][0];else i=c[i][1];
    }
    int tlast=getlast(ans);
    if (lx[ans]>r+1 && rx[tlast]!=l-1) {
        len++;
        splay(ans,0);
        int j=c[root][0];
        while (c[j][1]) j=c[j][1];
        splay(j,root);
        lx[len]=l;rx[len]=r;
        updata(len);
        link(j,len,1);
        updata(root);
        return ;
    }
    int tt=0,ll=l,rr=r;
    i=ans;
    if (pd_lr(ll,rr,lx[tlast],rx[tlast])) {i=tlast;tlast=getlast(tlast);}
    while (pd_lr(ll,rr,lx[i],rx[i])){
        if (lx[i]<ll) ll=lx[i];
        if (rx[i]>rr) rr=rx[i];
        tt++;
        sta[tt]=i;
        i=getnext(i);
    }
    rep(i,1,tt) del(sta[i]);
    splay(tlast,0);
    i=c[tlast][1];
    while (c[i][0]) i=c[i][0];
    splay(i,root);
    len++;
    lx[len]=ll;rx[len]=rr;
    maxs[len]=rr-ll+1;
    siz[len]=1;
    link(i,len,0);
    updata(root);
}
int main(){
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    scanf("%d%d",&n,&m);
    len=3;
    root=1;
    lx[1]=0;rx[1]=n-1;
    lx[2]=-1;rx[2]=-2;
    lx[3]=n+4;rx[3]=n+3;
    c[root][0]=2;
    c[root][1]=3;
    fa[2]=1;fa[3]=1;
    rek(i,3,1) updata(i);
    rep(i,1,m)
     {
        int c,x,y;
        scanf("%d",&c);
        if (c==1) {
                scanf("%d",&x);
                printf("%d\n",solve(x));
        }else
        {
            scanf("%d%d",&x,&y);
            int l=x;
            int r=min(x+y-1,n);
            cover(l,r);
        }
    }
    return 0;
}

题意不说了。

很显然,这题我们可以用splay做,每个节点维护一段连续的未被占用的区间,以及所在该子树最长的区间。。。这个非常好维护。。比较蛋疼的是2操作,要把所有相关的区间提取出来求并。。然后再插入新节点。。。就是模拟而已。当然也可以用动态开节点的线段树。。不过本人抖m写了个splay

代码:


51Nod 1489 蜥蜴和地下室 DFS

第一次在51Nod上用深搜.... 注意题目说的是血量小于0才死亡。我就把血量全部加一,最后判断血量小于等于0 为的是避免刚开始把第一个和最后一个弄死的时候的误差 #include #inc...

51nod 1478 括号序列的最长合法子段 (括号匹配)

括号匹配。

贪心(流水线调度问题) 51nod 1205

关于流水下调度之前上课,高老师讲了(一台和两台机器的调度问题,不过都是一次加工完成的,如果是这种情况就只需要每次挑加工时间最短的就可以了)。但是这题较之要难一点:一件物品加工两次:一件物品粗加工后,才...

51nod 1413 权势二进制 (思维+贪心)

1413 权势二进制 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 一...
  • gtuif
  • gtuif
  • 2017年12月09日 11:14
  • 12

51Nod-1874-字符串排序

ACM模版描述题解很简单的一个逆序数问题,不过因为一个坑点,WAWA 了好几发,一开始把 nn 和 mm 看反了……代码#include #include #include #include u...
  • f_zyj
  • f_zyj
  • 2017年12月10日 13:35
  • 104

51Nod-1417 天堂里的游戏(解方程)

1417 天堂里的游戏 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 多年后,每当Noder看...

51Nod-1005-大数加法

今天遇见一道细节问题特别多的题,写得我眼疼,题本身不难,难得是他的细节问题繁多,需要考虑的情况也甚多,稍有不慎就侧漏了,哈哈。 题的思路也很清晰,就是将最后的结果的正负的符号分离出来,剩下的就是高精度...
  • f_zyj
  • f_zyj
  • 2016年04月15日 03:39
  • 847

51NOD 1503 猪和回文

//https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1503#include using namespace std; c...

51nod 1255 字典序最小的子序列 神奇的栈用法

贪心算法 修改 隐藏话题 1255 字典序最小的子序列 题目来源: 天津大学OJ 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏 ...

51nod 1260 排列与二叉树

题意考虑这样的二叉树: 每个内部节点同时有左儿子和右儿子 恰好有 nn 个叶子 对任意满足上述条件的二叉树,我们按照中序遍历把每个叶子分别标上 11~nn,接下来,你可以任意交换每个内部节点的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:51nod 1207
举报原因:
原因补充:

(最多只允许输入30个字)