zoukankan      html  css  js  c++  java
  • 【BZOJ 4662】 4662: Snow (线段树+并查集)

    4662: Snow

    Time Limit: 40 Sec  Memory Limit: 256 MB
    Submit: 136  Solved: 47

    Description

    2333年的某一天,临冬突降大雪,主干道已经被雪覆盖不能使用。城
    主 囧·雪 决定要对主干道进行一次清扫。
    临冬城的主干道可以看为一条数轴。囧·雪 一共找来了n个清理工,第
    i个清理工的工作范围为[li,ri],也就是说这个清理工会把[li,ri]这一
    段主干道清理干净(当然已经被清理过的部分就被忽略了)。当然有可能主
    干道不能全部被清理干净,不过这也没啥关系。
    虽然 囧·雪 啥都不知道,但是他还是保证了不会出现某一个清理工的
    工作范围被另一个清理工完全包含的情况(不然就太蠢了)。
    作为临冬城主,囧·雪 给出了如下的清扫方案:
    在每一天开始的时候,每一个还没有工作过的清理工会观察自己工作
    范围内的道路,并且记下工作范围内此时还没有被清理的道路的长度(称
    为这个清理工的工作长度)。然后 囧·雪 会从中选择一个工作长度最小的
    清理工(如果两个清理工工作长度相同,那么就选择编号小的清理工)。然
    后被选择的这个清理工会清理自己的工作范围内的道路。为了方便检查工
    作质量,囧·雪 希望每一天只有一个清理工在工作。
    你要注意,清理工的工作长度是可能改变的,甚至有可能变成0。尽管
    如此,这个清理工也还是会在某一天工作。
    现在,囧·雪 想要知道每一天都是哪个清理工在工作?

    Input

    第一行两个整数t,n。分别表示主干道的长度(也就是说,主干道是数
    轴上[1,t]的这一段)以及清理工的人数。
    接下来n行,每行两个整数li,ri。意义如题。
    n<=3*10^5, 1<=li<ri<=t<=10^9,保证输入的li严格递增

    Output

    输出n行,第i行表示第i天工作的清理工的编号。

    Sample Input

    15 4
    1 6
    3 7
    6 11
    10 14

    Sample Output

    2
    1
    3
    4

    HINT

    Source

    【分析】

      其实这个也是线段树的经典了吧。

      之前做过好几题,就是每次操作的时候都会有一个节点删掉以后彻底没用,这样即使暴力也是不会超时的,因为每个点只会用一次。

      这里的这个点就是每个清洁工,我们只会询问他一次。

      跳出清扫区间这个圈子,用清洁工来建线段树。

      因为当你修改某段区间的时候,受影响的清洁工也是一个区间。

      先离散化,然后暴力删去区间,用并查集快速跳去已经失效的区间,每个位置只会操作一次,是可以过的。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 300010
      8 #define INF 0x7fffffff
      9 
     10 int nl[Maxn],nr[Maxn],nn[Maxn*2];
     11 
     12 struct node
     13 {
     14     int l,r,lc,rc,mn,lazy;
     15     int id;
     16 }tr[Maxn*2];
     17 
     18 int rt[Maxn*2];
     19 int rtt(int x)
     20 {
     21     if(rt[x]!=x) rt[x]=rtt(rt[x]);
     22     return rt[x];
     23 }
     24 
     25 int len=0;
     26 int build(int l,int r)
     27 {
     28     int x=++len;
     29     tr[x].l=l;tr[x].r=r;
     30     if(l!=r)
     31     {
     32         int mid=(l+r)>>1;
     33         tr[x].lc=build(l,mid);
     34         tr[x].rc=build(mid+1,r);
     35         tr[x].lazy=0;
     36         int lc=tr[x].lc,rc=tr[x].rc;
     37         if(tr[lc].mn<=tr[rc].mn) tr[x].mn=tr[lc].mn,tr[x].id=tr[lc].id;
     38         else tr[x].mn=tr[rc].mn,tr[x].id=tr[rc].id;
     39     }
     40     else tr[x].lc=tr[x].rc=0,tr[x].mn=nn[nr[l]]-nn[nl[l]],tr[x].id=l;
     41     return x;
     42 }
     43 
     44 void upd(int x)
     45 {
     46     if(tr[x].l==tr[x].r) return;
     47     int lc=tr[x].lc,rc=tr[x].rc;
     48     if(tr[lc].mn!=INF) tr[lc].mn-=tr[x].lazy;
     49     if(tr[rc].mn!=INF) tr[rc].mn-=tr[x].lazy;
     50     tr[lc].lazy+=tr[x].lazy;
     51     tr[rc].lazy+=tr[x].lazy;
     52     tr[x].lazy=0;
     53 }
     54 
     55 void change(int x,int y,int p)
     56 {
     57     if(tr[x].mn==INF) return;
     58     int mid=(tr[x].l+tr[x].r)>>1,lc=tr[x].lc,rc=tr[x].rc;
     59     if(p)
     60     {
     61         if(nl[tr[x].l]<=y&&y<nr[tr[x].l]&&nl[tr[x].r]<=y&&y<nr[tr[x].r])
     62         {
     63             tr[x].lazy+=nn[y+1]-nn[y];
     64             tr[x].mn-=nn[y+1]-nn[y];
     65             return;
     66         }
     67         if(tr[x].l==tr[x].r) return;
     68         upd(x);
     69         if(y<nr[mid]) change(lc,y,p);
     70         if(nl[mid+1]<=y) change(rc,y,p);
     71     }
     72     else
     73     {
     74         if(tr[x].l==tr[x].r)
     75         {
     76             tr[x].mn=INF;
     77             return;
     78         }
     79         upd(x);
     80         if(y<=mid) change(tr[x].lc,y,p);
     81         else change(tr[x].rc,y,p);
     82     }
     83     if(tr[lc].mn<=tr[rc].mn) tr[x].mn=tr[lc].mn,tr[x].id=tr[lc].id;
     84     else tr[x].mn=tr[rc].mn,tr[x].id=tr[rc].id;
     85 }
     86 
     87 
     88 struct nnode{int x,id;}t[Maxn*2];
     89 bool cmp(nnode x,nnode y) {return x.x<y.x;}
     90 
     91 int main()
     92 {
     93     int mx,n;
     94     scanf("%d%d",&mx,&n);
     95     for(int i=1;i<=n;i++) {scanf("%d%d",&nl[i],&nr[i]);
     96                       t[i*2-1].x=nl[i];t[i*2-1].id=i;t[i*2].x=nr[i];t[i*2].id=-i;}
     97     sort(t+1,t+1+2*n,cmp);
     98     mx=1;nl[t[1].id]=1;nn[1]=t[1].x;
     99     for(int i=2;i<=2*n;i++)
    100     {
    101         if(t[i].x!=t[i-1].x) mx++,nn[mx]=t[i].x;
    102         if(t[i].id>0) nl[t[i].id]=mx;
    103         else nr[-t[i].id]=mx;
    104     }
    105     build(1,n);
    106     for(int i=1;i<=mx;i++) rt[i]=i;
    107     for(int i=1;i<=n;i++)
    108     {
    109         int x=tr[1].id;
    110         printf("%d
    ",x);
    111         change(1,x,0);
    112         int st=rtt(nl[x]);
    113         for(int j=st;j<nr[x];)
    114         {
    115             change(1,j,1);
    116             rt[j]=rtt(j+1);
    117             j=rt[j];
    118         }
    119     }
    120     return 0;
    121 }
    View Code

    2017-03-27 09:29:36

  • 相关阅读:
    使用 requests 维持会话
    使用 requests 发送 POST 请求
    使用 requests 发送 GET 请求
    requests 安装
    使用 urllib 分析 Robots 协议
    使用 urllib 解析 URL 链接
    使用 urllib 处理 HTTP 异常
    使用 urllib 处理 Cookies 信息
    使用 urllib 设置代理服务
    按单生产程序发布
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6625209.html
Copyright © 2011-2022 走看看