• 【ZJOI2007】捉迷藏 小小的总结


    2019-01-09

    22:56:33

    终于终于把这道题目做掉了。。。

    做了两个晚上。。不知道为什么自己如此之笨。。

    在洛谷上断断续续一共交了24次,感觉自己都要被封号了。

    昨天花半个晚上从零开始研究动态的 淀粉质 点分治,又研究了好久的标程,然后又动手写了半个晚上。

    好不容易过了样例,交到洛谷上一测,满屏的 MLE 然后把氧气优化关掉 TLE ?!!!? (手动懵逼

    开始了漫长的 找不同(对比标程) 之旅,找了很久都没有结果,就回家了。

    还嘲笑了一波 标称那堆神秘的分层操作,不知道哪里来的一些RMQ操作,我用倍增就可以求距离了(这是个Flag,这是第二天啪啪打脸的伏笔)


    第二天

    中午放学一回家就开始检查程序,又交了好几次,每一次都是零分,每一次都是MLE(连WA的机会都不给我吗!!)

    我真的感觉我的程序和标程除了倍增求距离的方法不同其它的几乎都没有差别了好吗?!(坐等打脸)

    去上学 去上学 这几天停课复习会考科目(12号会考),春哥说:“辣么简单的考试你们担心什么啦~”

    晚自习继续来到机房修改程序。

    EXM??? 我居然发现我把重心 vis掉的地方写错了 果然,照着标程写会受惩罚的。。。

    自信满满地交上去一看 只有20分!(还T了一组。。

    路漫漫其修远兮

    凉 真的找不到错啊啊啊啊啊啊啊啊! 痛苦!!!

    冷静地写了对拍

    镇定地把中间数据输出来调

    冷漠地寻找错误答案与正确答案之间的蛛丝马迹

    镇静地把数据规模调到1e5

    我终于终于发现 我的倍增写错了!!!!!

     父亲节点 f[x][0] 完全赋错值了,直接就写成了 f[x][0]=fa (...)

    改好后信心满满地交上去 

    90分。。。有一组超时了(还开了O2优化)

    冷静下来 我思考了一下,每次都倍增的话不是会很慢吗?! 

    题目的查询有那么多次 肯定超时啊!

    难怪标程用了ST表来查公共祖先

    难怪有一个神秘的RMQ 就是来求LCA的啊!!

    ST表可以通过 O(nlogn) 的复杂度代价来得到 O(1) 查询的啊。

    啪啪啪 打脸

    感到了自负对我深深地恶意。。

    然后马不停蹄地开始改倍增,全部换成RMQ。

    折腾了十几分钟,再次提交。

    还是90! 第四组居然 WA了!! 五雷轰顶!!

    又找了好久的错,才发现 DFS 时 由于写太快,少了一条语句。。

    然后终于AC了 

    完结撒花!!

    一道题目写了这么久,真的要好好反思一下了,写程序时一定要带着脑子思考,不能照着标程写啊。

    “剽窃”别人的智慧结晶是不会有好下场的。。

    附上写到麻木的200行代码

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<string>
      6 #include<ctime>
      7 #include<cmath>
      8 #include<algorithm>
      9 #include<cctype>
     10 #include<iomanip>
     11 #include<queue>
     12 
     13 #define For(i,a,b) for(int i=a;i<=b;++i)
     14 #define Dwn(i,a,b) for(int i=a;i>=b;--i)
     15 #define Pn putchar('
    ')
     16 
     17 using namespace std;
     18 const int N=1e5+10;
     19 struct Heap {
     20     priority_queue<int> h, d;
     21     void add(int x){ 
     22         h.push(x);
     23         return;
     24     }
     25     void del(int x){ 
     26         d.push(x);
     27         return;
     28     }
     29     void AorP(int x,int f){
     30         if(f) add(x);
     31         else del(x); 
     32         return;
     33     }
     34     void fix(){ 
     35         while(d.size()&&h.top()==d.top())
     36             h.pop(),d.pop();
     37         return;
     38     }
     39     void pop(){ 
     40         fix();
     41         h.pop();
     42         return;
     43     }
     44     int fst(){ 
     45         fix(); 
     46         return h.top(); 
     47     }
     48     int scd(){ 
     49         int a,b;
     50         a=fst();
     51         pop();
     52         b=fst();
     53         add(a);
     54         return b;
     55     }
     56     int size(){ 
     57         return h.size()-d.size();
     58     }
     59 } s1[N], s2[N], s3;
     60 
     61 int head[N],nxt[N*2],v[N*2],cnt=1;
     62 int siz[N],f[N*2][21],dis[N],Mxs[N],Wfa[N];
     63 bool vis[N*2];
     64 int n,m,x,y,root,tot,Frt,Qsum=0,LD[N],Q;
     65 char c[20];
     66 
     67 
     68 inline void read(int &v){
     69     v=0;
     70     char c=getchar();
     71     while(c<'0'||c>'9')c=getchar();
     72     while(c>='0'&&c<='9')v=v*10+c-'0',c=getchar();
     73 }
     74 void write(int x){
     75     if(x>9)write(x/10);
     76     int xx=x%10;
     77     putchar(xx+'0');
     78 }
     79 void add(int ux,int vx){
     80     cnt++;
     81     nxt[cnt]=head[ux]; head[ux]=cnt; v[cnt]=vx;
     82     cnt++;
     83     nxt[cnt]=head[vx]; head[vx]=cnt; v[cnt]=ux;
     84 }
     85 
     86 void dfsRT(int x,int fa){
     87     siz[x]=1; Mxs[x]=0;
     88     for(int i=head[x];i;i=nxt[i]){
     89         int vv=v[i];
     90         if(vv==fa||vis[i])continue;
     91         dfsRT(vv,x);
     92         siz[x]+=siz[vv];
     93         Mxs[x]=max(Mxs[x],siz[vv]);
     94     }
     95     if(tot-siz[x]>Mxs[x])Mxs[x]=tot-siz[x];
     96     if(Mxs[x]<Mxs[root])root=x;
     97 }
     98 int getWRT(int x,int fa,int sz){
     99     root=0; tot=sz; Mxs[0]=2147483600;
    100     dfsRT(x,fa); 
    101     return root;
    102 }
    103 void dfsBD(int x,int fa,int dep,Heap &s){
    104     s.add(dep);
    105     for(int i=head[x];i;i=nxt[i]){
    106         int vv=v[i];
    107         if(vis[i]||vv==fa)continue;
    108         dfsBD(vv,x,dep+1,s);
    109     }
    110 }
    111 void AddS3(Heap &s){
    112     if(s.size()>=2){
    113         s3.add(s.fst()+s.scd());
    114     }
    115     return;
    116 }
    117 void DelS3(Heap &s){
    118     if(s.size()>=2){
    119         s3.del(s.fst()+s.scd());
    120     }
    121 }
    122 void work(int x){ 
    123     s2[x].add(0);
    124     for(int i=head[x];i;i=nxt[i]){
    125         int vv=v[i];
    126         if(vis[i])continue;
    127         vis[i]=vis[i^1]=1; 
    128         Heap s;
    129         dfsBD(vv,0,1,s);
    130         int nxtRt=getWRT(vv,x,siz[vv]); 
    131         Wfa[nxtRt]=x;
    132         s1[nxtRt]=s;
    133         s2[x].add(s1[nxtRt].fst());
    134         work(nxtRt);
    135     }
    136     AddS3(s2[x]);
    137     return;
    138 }
    139 
    140 
    141 int pos[2*N][21],dfx[N*2],fr[N],dpx[N*2],dep[N],ID=0;
    142 void dfsLCA(int x,int d,int fa){
    143     fr[x]=++ID;
    144     dpx[ID]=d; dep[x]=d;
    145     for(int i=head[x];i;i=nxt[i]){
    146         int vv=v[i];
    147         if(vv==fa)continue;
    148         dfsLCA(vv,d+1,x);
    149         ID++;
    150         dpx[ID]=d;
    151     }
    152 }
    153 void inLCA(){
    154     For(i,1,ID)f[i][0]=dpx[i];
    155     for(int j=1;(1<<j)<=ID;++j)
    156      for(int i=1;i+(1<<j)-1<=ID;++i){
    157          f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    158      }
    159 }
    160  
    161 int LCA(int x,int y){
    162     int l=fr[x];    int r=fr[y];
    163     if(x==y)return 0;
    164     if(l>r)swap(l,r);
    165     int Kx=-1;
    166     int dx=r-l+1;
    167     while((1<<(Kx+1))<=dx)Kx++; 
    168     int ans;
    169     ans=min(f[r-(1<<Kx)+1][Kx],f[l][Kx]);
    170     return ans; 
    171 }
    172 
    173  
    174 int Dis(int x,int y){
    175     return dep[x]+dep[y]-2*LCA(x,y) ;
    176 }
    177 
    178 void upD(int x,int fg){ 
    179     DelS3(s2[x]);
    180     s2[x].AorP(0,fg);
    181     AddS3(s2[x]); 
    182     for(int u=x;Wfa[u];u=Wfa[u]){
    183         DelS3(s2[Wfa[u]]); 
    184         if(s1[u].size())
    185             s2[Wfa[u]].del(s1[u].fst()); 
    186         s1[u].AorP(Dis(Wfa[u],x),fg);
    187         if(s1[u].size())
    188             s2[Wfa[u]].add(s1[u].fst());
    189         AddS3(s2[Wfa[u]]);
    190     }
    191     return;
    192 }
    193 int main(){
    194     //freopen("ex.in","r",stdin);
    195     //freopen("ex.out","w",stdout);
    196     memset(vis,0,sizeof(vis));
    197 //    memset(f,-1,sizeof(f));
    198     read(n);
    199     For(i,1,n-1){
    200         read(x); read(y); add(x,y);
    201     }
    202     Frt=getWRT(1,0,n); 
    203     dfsLCA(Frt,0,0); inLCA();
    204     work(Frt); 
    205     read(Q);
    206     Qsum=n;
    207     For(i,1,Q){  
    208         scanf("%s",c);  ;
    209         if(c[0]=='C'){
    210             read(x);
    211             upD(x,LD[x]);
    212             if(LD[x])Qsum++;
    213             else Qsum--;
    214             LD[x]=LD[x]^1;
    215         }else{
    216             if(Qsum==1)write(0),Pn;
    217             if(Qsum==0)putchar('-'),putchar('1'),Pn;
    218             if(Qsum>=2){
    219                 int fn=s3.fst();
    220                 write(fn);
    221                 Pn;
    222             }
    223         }
    224     }
    225     return 0;
    226 }
  • 相关阅读:
    linux(ubuntu)设置开机启动
    mysql 数据库迁移
    maven GroupId和ArtifactID
    Android内存溢出与内存泄漏
    Android性能优化方向和相关工具
    安卓 px,dpi,dp,ps的区别与联系
    python 深浅拷贝
    公网ip和私网ip
    打开系统设置页
    如何用代码开启“个人热点”功能?如何用代码把iOS设备设置成一个无线路由?
  • 原文地址:https://www.cnblogs.com/HLAUV/p/10247516.html
Copyright © 2020-2023  润新知