zoukankan      html  css  js  c++  java
  • BZOJ 3514 Codechef MARCH14 GERALD07加强版

    从CC抠的题 xyz大神直接用分块秒 虽然会MLE+TLE

    时限被改成40s了,我觉得30s足够了吧……

    考虑从左至右加入每一条边,加入某条边成环的环那么这条边对答案就没有影响。那么只要环上标号最小的边没被加入就会对答案有影响。

    所以问题变成了区间询问小于某个数的数有多少个,这个主席树就行了。

    至于前面那一步,用动态树求出来就行了。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<cctype>
      5 #include<algorithm>
      6  
      7 using namespace std;
      8  
      9 const int BUF_SIZE = 30;
     10 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
     11   
     12 #define PTR_NEXT() 
     13     { 
     14         buf_s ++; 
     15         if (buf_s == buf_t) 
     16         { 
     17             buf_s = buf; 
     18             buf_t = buf + fread(buf, 1, BUF_SIZE, stdin); 
     19         } 
     20     }
     21    
     22 #define readint(_n_) 
     23     { 
     24         while (*buf_s != '-' && !isdigit(*buf_s)) 
     25             PTR_NEXT(); 
     26         bool register _nega_ = false; 
     27         if (*buf_s == '-') 
     28         { 
     29             _nega_ = true; 
     30             PTR_NEXT(); 
     31         } 
     32         int register _x_ = 0; 
     33         while (isdigit(*buf_s)) 
     34         { 
     35             _x_ = _x_ * 10 + *buf_s - '0'; 
     36             PTR_NEXT(); 
     37         } 
     38         if (_nega_) 
     39             _x_ = -_x_; 
     40         (_n_) = (_x_); 
     41     }
     42 
     43 const int maxn=200010;
     44 const int maxp=maxn*20;
     45 const int INF=0x3f3f3f3f;
     46  
     47 int n,m,k,wmt,type,s[maxn],e[maxn],root[maxn];
     48  
     49 struct tree_node
     50 {
     51     int l,r;
     52     int sum;
     53     void init()
     54     {
     55         l=r=sum=0;
     56     }
     57 }y[maxp];
     58  
     59 int newnode()
     60 {
     61     y[++wmt].init();
     62     return wmt;
     63 }
     64  
     65 int insert(int p,int l,int r,int v)
     66 {
     67     int pp=newnode();
     68     if (l==r)
     69     {
     70         y[pp].sum=y[p].sum+1;
     71         return pp;
     72     }
     73     int m=(l+r)>>1;
     74     if (v<=m)
     75     {
     76         y[pp].l=insert(y[p].l,l,m,v);
     77         y[pp].r=y[p].r;
     78     }
     79     else
     80     {
     81         y[pp].l=y[p].l;
     82         y[pp].r=insert(y[p].r,m+1,r,v);
     83     }
     84     y[pp].sum=y[y[pp].l].sum+y[y[pp].r].sum;
     85     return pp;
     86 }
     87  
     88 int query(int p1,int p2,int l,int r,int nowl,int nowr)
     89 {
     90     if (nowl<=l && r<=nowr) return y[p1].sum-y[p2].sum;
     91     int m=(l+r)>>1;
     92     if (nowl<=m)
     93     {
     94         if (m<nowr) return query(y[p1].l,y[p2].l,l,m,nowl,nowr)+query(y[p1].r,y[p2].r,m+1,r,nowl,nowr);
     95         else return query(y[p1].l,y[p2].l,l,m,nowl,nowr);
     96     }
     97     else return query(y[p1].r,y[p2].r,m+1,r,nowl,nowr);
     98 }
     99  
    100 struct node
    101 {
    102     int l,r,f,v,minv;
    103     bool rev,rt;
    104     void init()
    105     {
    106         l=r=f=0;
    107         rev=false;
    108         rt=true;
    109         minv=INF;
    110     }
    111 }z[maxn<<1];
    112  
    113 void update(int x)
    114 {
    115     z[x].minv=z[x].v;
    116     if (z[x].l) z[x].minv=min(z[x].minv,z[z[x].l].minv);
    117     if (z[x].r) z[x].minv=min(z[x].minv,z[z[x].r].minv);
    118 }
    119  
    120 void rot_l(int x)
    121 {
    122     int y=z[x].r;
    123     z[x].r=z[y].l;
    124     z[y].l=x;
    125     if (z[x].rt) z[x].rt^=1,z[y].rt^=1;
    126     else
    127     {
    128         if (z[z[x].f].l==x) z[z[x].f].l=y;
    129         else z[z[x].f].r=y;
    130     }
    131     z[y].f=z[x].f;
    132     z[x].f=y;
    133     z[z[x].r].f=x;
    134 }
    135  
    136 void rot_r(int x)
    137 {
    138     int y=z[x].l;
    139     z[x].l=z[y].r;
    140     z[y].r=x;
    141     if (z[x].rt) z[x].rt^=1,z[y].rt^=1;
    142     else
    143     {
    144         if (z[z[x].f].l==x) z[z[x].f].l=y;
    145         else z[z[x].f].r=y;
    146     }
    147     z[y].f=z[x].f;
    148     z[x].f=y;
    149     z[z[x].l].f=x;
    150 }
    151  
    152 void push(int x)
    153 {
    154     if (z[x].rev)
    155     {
    156         z[z[x].l].rev^=1;
    157         swap(z[z[x].l].l,z[z[x].l].r);
    158         z[z[x].r].rev^=1;
    159         swap(z[z[x].r].l,z[z[x].r].r);
    160         z[x].rev^=1;
    161     }
    162 }
    163  
    164 void splay(int x)
    165 {
    166     while (!z[x].rt)
    167     {
    168         int f=z[x].f;
    169         int ff=z[f].f;
    170         push(ff);
    171         push(f);
    172         push(x);
    173         if (z[f].rt)
    174         {
    175             if (z[f].l==x) rot_r(f);
    176             else rot_l(f);
    177         }
    178         else
    179         {
    180             if (z[ff].l==f && z[f].l==x)
    181             {
    182                 rot_r(ff);
    183                 rot_r(f);
    184             }
    185             if (z[ff].l==f && z[f].r==x)
    186             {
    187                 rot_l(f);
    188                 rot_r(ff);
    189             }
    190             if (z[ff].r==f && z[f].l==x)
    191             {
    192                 rot_r(f);
    193                 rot_l(ff);
    194             }
    195             if (z[ff].r==f && z[f].r==x)
    196             {
    197                 rot_l(ff);
    198                 rot_l(f);
    199             }
    200         }
    201         update(ff);
    202         update(f);
    203     }
    204     update(x);
    205     push(x);
    206 }
    207  
    208 void access(int x)
    209 {
    210     int p1=x,p2=0;
    211     do
    212     {
    213         splay(p1);
    214         z[z[p1].r].rt=true;
    215         z[p2].rt=false;
    216         z[p1].r=p2;
    217         z[p2].f=p1;
    218         update(p1);
    219         p2=p1;
    220         p1=z[p1].f;
    221     }while(p1);
    222 }
    223  
    224 void join(int p1,int p2)
    225 {
    226     access(p1);
    227     splay(p1);
    228     z[p1].rev^=1;
    229     swap(z[p1].l,z[p1].r);
    230     z[p1].f=p2;
    231 }
    232  
    233 void cut(int p1,int p2)
    234 {
    235     access(p1);
    236     splay(p2);
    237     if (z[p2].f==p1) z[p2].f=0;
    238     else
    239     {
    240         access(p2);
    241         splay(p1);
    242         z[p1].f=0;
    243     }
    244 }
    245  
    246 bool connect(int p1,int p2)
    247 {
    248     access(p2);
    249     for (;p1;p1=z[p1].f)
    250     {
    251         splay(p1);
    252         if (!z[p1].f) break;
    253     }
    254     for (;z[p1].r;p1=z[p1].r);
    255     return p1==p2;
    256 }
    257  
    258 int query(int x,int y)
    259 {
    260     access(y);
    261     int ans=INF;
    262     for (y=0;x;x=z[x].f)
    263     {
    264         splay(x);
    265         if (!z[x].f)
    266         {
    267             ans=z[x].v;
    268             if (y) ans=min(ans,z[y].minv);
    269             if (z[x].r) ans=min(ans,z[z[x].r].minv);
    270             break;
    271         }
    272         z[z[x].r].rt=true;
    273         z[y].rt=false;
    274         z[x].r=y;
    275         y=x;
    276         update(y);
    277     }
    278     return ans;
    279 }
    280  
    281  
    282 int main()
    283 {
    284 
    285     readint(n);
    286     readint(m);
    287     readint(k);
    288     readint(type);
    289     for (int a=1;a<=m;a++)
    290     {
    291         readint(s[a]);
    292         readint(e[a]);
    293     }
    294     for (int a=1;a<=n+m;a++)
    295     {
    296         z[a].init();
    297         if (a<=n) z[a].v=z[a].minv=INF;
    298         else z[a].v=z[a].minv=a-n;
    299     }
    300     wmt=0;
    301     for (int a=1;a<=m;a++)
    302     {
    303         int p1=s[a],p2=e[a];
    304         if (p1==p2)
    305         {
    306             root[a]=insert(root[a-1],0,m,a);
    307             continue;
    308         }
    309         if (connect(p1,p2))
    310         {
    311             int value=query(p1,p2);
    312             cut(value+n,s[value]);
    313             cut(value+n,e[value]);
    314             root[a]=insert(root[a-1],0,m,value);
    315             join(a+n,p1);
    316             join(a+n,p2);
    317         }
    318         else 
    319         {
    320             root[a]=insert(root[a-1],0,m,0);
    321             join(a+n,p1);
    322             join(a+n,p2);
    323         }
    324     }
    325     int l,r;
    326     for (int a=1,lastans=0;a<=k;a++)
    327     {
    328         readint(l);
    329         readint(r);
    330         if (type==1) l^=lastans,r^=lastans;
    331         printf("%d
    ",(lastans=n-query(root[r],root[l-1],0,m,0,l-1)));
    332     }
    333 
    334     return 0;
    335 }
    View Code
  • 相关阅读:
    alias这个命令还是很有用的
    为什么不推荐用破解版的winrar
    chrome headless
    关于PDF的一些书籍
    PDF的一些工具
    3DPDF是个什么东西?
    你可能不知道的pdf的功能
    为什么一些公司把dwg文件转化为pdf
    关于pdf阅读器的选择
    接外包怎么保护自己的作品
  • 原文地址:https://www.cnblogs.com/zhonghaoxi/p/3651591.html
Copyright © 2011-2022 走看看