zoukankan      html  css  js  c++  java
  • bzoj3514

    好题+数据结构神题+感人肺腑pascal被卡系列,我下面的代码几乎写到最优
    可怎耐bzoj上pascal开的是O1,c++开的是O2,这怎么可能跑得过!!!
    还是说说方法吧,这是一道算贡献的好题,因为我们不可能把边加进去依次算连通块个数
    我们考虑在区间[l,r]中每条边i是否能使两个连通块变成1个,什么样的边可以呢?
    显然,这条边端点所在的连通块在i加入之前不连通或者是使这两个连通块相连的边号<l
    这样算法就呼之欲出了,我们首先依次把边i加入,如果构成环,则弹出环上编号最小的边并记录,否则记为0
    这里我们可以用link cut tree解决
    下面每次询问,我们只要求[l,r]有多少个数小于l即可
    这题有是否强制在线两种情况,在线可以直接rush,但是我第一次TLE之后又写了一遍离线,发现比原来快但还是远远慢于只在线的c++,实在没办法只好弃疗,说一下两种情况
    在线:显然这是主席树的经典问题
    离线:注意这个个数是满足区间减法的,于是我们可以拆成两个求前缀询问并排序(注意这里用计数排序才有显著的提升),然后按边编号的顺序依次加入然后用树状数组统计,具体见程序

      1 const inf=100000007;
      2 type node=record
      3        l,r,s:longint;
      4      end;
      5      way=record
      6        s,e:longint;
      7      end;
      8      point=record
      9        be,op,y:longint;
     10      end;
     11      xxx=record
     12        po,next:longint;
     13      end;
     14 
     15 var son:array[0..400010,1..2] of longint;
     16     q,w,v,fa:array[0..400010] of longint;
     17     qq:array[0..410010] of point;
     18     ee:array[0..400010] of xxx;
     19     rev:array[0..400010] of boolean;
     20     tree:array[0..200010*22] of node;
     21     e:array[0..200010] of way;
     22     p,f,a,h,anss:array[0..200010] of longint;
     23     len,j,k1,k2,n,m,k,ty,t,i,ans,l,r,mm:longint;
     24 
     25 function min(a,b:longint):longint;
     26   begin
     27     if w[a]>w[b] then exit(b) else exit(a);
     28   end;
     29 
     30 function getf(x:longint):longint;
     31   begin
     32     if f[x]<>x then f[x]:=getf(f[x]);
     33     exit(f[x]);
     34   end;
     35 
     36 procedure swap(var a,b:longint);
     37   var c:longint;
     38   begin
     39     c:=a;
     40     a:=b;
     41     b:=c;
     42   end;
     43 
     44 function root(x:longint):boolean;
     45   begin
     46     exit((son[fa[x],1]<>x) and (son[fa[x],2]<>x));
     47   end;
     48 
     49 procedure update(x:longint);
     50   begin
     51     v[x]:=min(x,min(v[son[x,1]],v[son[x,2]]));
     52   end;
     53 
     54 procedure push(x:longint);
     55   begin
     56     if rev[x] then
     57     begin
     58       swap(son[x,1],son[x,2]);
     59       rev[son[x,1]]:=not rev[son[x,1]];
     60       rev[son[x,2]]:=not rev[son[x,2]];
     61       rev[x]:=false;
     62     end;
     63   end;
     64 
     65 procedure rotate(x,w:longint);
     66   var y:longint;
     67   begin
     68     y:=fa[x];
     69     if not root(y) then
     70     begin
     71       if son[fa[y],1]=y then son[fa[y],1]:=x
     72       else son[fa[y],2]:=x;
     73     end;
     74     fa[x]:=fa[y];
     75     son[y,3-w]:=son[x,w];
     76     if son[x,w]<>0 then fa[son[x,w]]:=y;
     77     son[x,w]:=y;
     78     fa[y]:=x;
     79     update(y);
     80   end;
     81 
     82 procedure splay(x:longint);
     83   var i,s,y:longint;
     84       fl:boolean;
     85   begin
     86     i:=x;
     87     s:=0;
     88     while not root(i) do
     89     begin
     90       inc(s);
     91       q[s]:=i;
     92       i:=fa[i];
     93     end;
     94     inc(s);
     95     q[s]:=i;
     96     for i:=s downto 1 do
     97       push(q[i]);
     98     if s=1 then exit;
     99     fl:=true;
    100     while fl do
    101     begin
    102       y:=fa[x];
    103       if y=q[s] then
    104       begin
    105         if son[y,1]=x then rotate(x,2)
    106         else rotate(x,1);
    107         fl:=false;
    108       end
    109       else begin
    110         if fa[y]=q[s] then fl:=false;
    111         if son[fa[y],1]=y then
    112         begin
    113           if son[y,1]=x then rotate(y,2)
    114           else rotate(x,1);
    115           rotate(x,2);
    116         end
    117         else begin
    118           if son[y,1]=x then rotate(x,2)
    119           else rotate(y,1);
    120           rotate(x,1);
    121         end;
    122       end;
    123     end;
    124     update(x);
    125   end;
    126 
    127 procedure access(x:longint);
    128   var y:longint;
    129   begin
    130     y:=0;
    131     repeat
    132       splay(x);
    133       son[x,2]:=y;
    134       update(x);
    135       y:=x;
    136       x:=fa[x];
    137     until x=0;
    138   end;
    139 
    140 procedure makeroot(x:longint);
    141   begin
    142     access(x);
    143     splay(x);
    144     rev[x]:=not rev[x];
    145   end;
    146 
    147 procedure link(x,y:longint);
    148   begin
    149     makeroot(x);
    150     fa[x]:=y;
    151   end;
    152 
    153 procedure path(x,y:longint);
    154   begin
    155     makeroot(x);
    156     access(y);
    157     splay(y);
    158   end;
    159 
    160 procedure cut(x,y:longint);
    161   begin
    162     path(x,y);
    163     son[y,1]:=0;
    164     fa[x]:=0;
    165   end;
    166 
    167 function build(l,r:longint):longint;
    168   var m,q:longint;
    169   begin
    170     inc(t);
    171     if l=r then exit(t)
    172     else begin
    173       m:=(l+r) shr 1;
    174       q:=t;
    175       tree[q].l:=build(l,m);
    176       tree[q].r:=build(m+1,r);
    177       exit(q);
    178     end;
    179   end;
    180 
    181 function add(l,r,last,x:longint):longint;
    182   var m,q:longint;
    183   begin
    184     inc(t);
    185     if l=r then
    186     begin
    187       tree[t].s:=tree[last].s+1;
    188       exit(t);
    189     end
    190     else begin
    191       m:=(l+r) shr 1;
    192       q:=t;
    193       if x<=m then
    194       begin
    195         tree[q].r:=tree[last].r;
    196         tree[q].l:=add(l,m,tree[last].l,x);
    197       end
    198       else begin
    199         tree[q].l:=tree[last].l;
    200         tree[q].r:=add(m+1,r,tree[last].r,x);
    201       end;
    202       tree[q].s:=tree[tree[q].l].s+tree[tree[q].r].s;
    203       exit(q);
    204     end;
    205   end;
    206 
    207 function ask(l,r,x,y:longint):longint;
    208   var m,s:longint;
    209   begin
    210     if l=r then exit(tree[y].s-tree[x].s)
    211     else begin
    212       m:=(l+r) shr 1;
    213       if k1<=m then exit(ask(l,m,tree[x].l,tree[y].l))
    214       else begin
    215         s:=tree[tree[y].l].s-tree[tree[x].l].s;
    216         exit(s+ask(m+1,r,tree[x].r,tree[y].r));
    217       end;
    218     end;
    219   end;
    220 
    221 procedure cha(var a,b:point);
    222   var c:point;
    223   begin
    224     c:=a;
    225     a:=b;
    226     b:=c;
    227   end;
    228 
    229 function lowbit(x:longint):longint;
    230   begin
    231     exit(x and (-x));
    232   end;
    233 
    234 procedure jia(x,y:longint);
    235   begin
    236     inc(len);
    237     ee[len].po:=y;
    238     ee[len].next:=p[x];
    239     p[x]:=len;
    240   end;
    241 
    242 procedure ins(x:longint);
    243   begin
    244     while x<=m+1 do
    245     begin
    246       inc(h[x]);
    247       x:=x+lowbit(x);
    248     end;
    249   end;
    250 
    251 function an(x:longint):longint;
    252   begin
    253     an:=0;
    254     while x>0 do
    255     begin
    256       an:=an+h[x];
    257       x:=x-lowbit(x);
    258     end;
    259   end;
    260 
    261 begin
    262   readln(n,m,k,ty);
    263   for i:=1 to n do
    264   begin
    265     f[i]:=i;
    266     w[i]:=inf;
    267   end;
    268   t:=n;
    269   w[0]:=inf;
    270   for i:=1 to m do
    271   begin
    272     readln(e[i].s,e[i].e);
    273     if e[i].s=e[i].e then
    274     begin
    275       a[i]:=i;
    276       continue;
    277     end;
    278     k1:=getf(e[i].s);
    279     k2:=getf(e[i].e);
    280     if k1=k2 then  //并查集判连通
    281     begin
    282       path(e[i].s,e[i].e);
    283       l:=v[e[i].e];
    284       a[i]:=w[l];
    285       cut(e[w[l]].s,l);
    286       cut(e[w[l]].e,l);
    287     end
    288     else f[k1]:=k2;
    289     inc(t);  w[t]:=i;
    290     link(e[i].s,t);
    291     link(e[i].e,t);
    292   end;
    293   if ty=1 then  //在线做法
    294   begin
    295     t:=0;
    296     h[0]:=build(0,m);
    297     for i:=1 to m do
    298     begin
    299       h[i]:=add(0,m,h[i-1],a[i]);
    300     end;
    301     ans:=0;
    302     for i:=1 to k do
    303     begin
    304       readln(l,r);
    305       l:=l xor ans;
    306       r:=r xor ans;
    307       if l>r then swap(l,r);
    308       k1:=l-1;
    309       ans:=n-ask(0,m,h[l-1],h[r]);
    310       writeln(ans);
    311     end;
    312   end
    313   else begin  //离线做法
    314     t:=0;
    315     for i:=1 to k do
    316     begin
    317       readln(l,r);
    318       inc(t);
    319       qq[t].op:=-1;
    320       qq[t].y:=l;
    321       qq[t].be:=i;
    322       jia(r,t);
    323       inc(t);
    324       qq[t].op:=1;
    325       jia(l-1,t);
    326       qq[t].y:=l;
    327       qq[t].be:=i;
    328     end;
    329     j:=1;
    330     a[m+1]:=inf;
    331     for i:=0 to m do 
    332     begin
    333       while j<=i do
    334       begin
    335         ins(a[j]+1); //树状数组编号从1开始,所以+1
    336         inc(j);
    337       end;
    338       l:=p[i];
    339       while l<>0 do
    340       begin
    341         r:=ee[l].po;
    342         inc(anss[qq[r].be],qq[r].op*an(qq[r].y));
    343         l:=ee[l].next;
    344       end;
    345     end;
    346     for i:=1 to k do
    347       writeln(anss[i]+n);
    348   end;
    349 end.  
    View Code
  • 相关阅读:
    只允许更改任务状态,其他项不允许更改
    已有发料的工单不能变更为取消状态
    不允许车间任务新建
    完工原因栏必输
    不允许计划员修改任务的完成、完工不计费状态
    虚拟件零成本控制
    成本监控只能修改完成或完工不计费状态作业
    完工子库必输
    发料不允许更改发料日期
    车间任务不可更改开始时间/完成时间
  • 原文地址:https://www.cnblogs.com/phile/p/4472950.html
Copyright © 2011-2022 走看看