• Query on a tree IV SPOJ


    https://vjudge.net/problem/SPOJ-QTREE4

    点分就没有一道不卡常的?

    卡常记录:

    1.把multiset换成手写的带删除堆(套用pq)(作用很大)

    2.把带删除堆里面pq换成用vector+push_heap/pop_heap(作用较小)

      1 #pragma GCC optimize("Ofast")
      2 #pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
      3 #pragma GCC diagnostic error "-fwhole-program"
      4 #pragma GCC diagnostic error "-fcse-skip-blocks"
      5 #pragma GCC diagnostic error "-funsafe-loop-optimizations"
      6 #pragma GCC diagnostic error "-std=c++14"
      7 #include<cstdio>
      8 #include<algorithm>
      9 #include<queue>
     10 using namespace std;
     11 struct E
     12 {
     13     int to,nxt,d;
     14 }e[200100];
     15 int f1[100100],ne;
     16 int ff[100100],n,sum,fx[100100],sz[100100];
     17 int eu[200100],pos[200100],dpx[200100],dpx2[200100],st[200100][20],log2x[200100],lft[30];
     18 int root;
     19 bool fl[100100],vis[100100];
     20 struct xxx
     21 {
     22 priority_queue<int> q1,q2;int sz;
     23 void insert(int x){q1.push(x);++sz;}
     24 void erase(int x){q2.push(x);--sz;}
     25 int size()    {return sz;}
     26 void cl()
     27 {
     28     while(!q1.empty()&&!q2.empty()&&q1.top()==q2.top())    q1.pop(),q2.pop();
     29 }
     30 void pop()
     31 {
     32     cl();q1.pop();--sz;
     33 }
     34 int top()
     35 {
     36     cl();return q1.top();
     37 }
     38 bool empty()    {return sz==0;}
     39 };
     40 xxx s[100100],s2[100100],s3;
     41 //s[i]:i点管辖的连通块各个点到i点上层重心的距离
     42 //s2[i]:i点的各个下层重心的s的最大值,**再加上一个0(i点到自身距离)
     43 //s3:各个s2的前2大值之和
     44 int getdis(int x,int y)
     45 {
     46     int l=pos[x],r=pos[y];if(l>r)    swap(l,r);
     47     int k=log2x[r-l+1],t=dpx[pos[st[l][k]]]>dpx[pos[st[r-lft[k]+1][k]]]?st[r-lft[k]+1][k]:st[l][k];
     48     return dpx2[pos[x]]+dpx2[pos[y]]-2*dpx2[pos[t]];
     49 }
     50 void getroot(int u,int fa)
     51 {
     52     sz[u]=1;fx[u]=0;
     53     for(int k=f1[u];k;k=e[k].nxt)
     54         if(!vis[e[k].to]&&e[k].to!=fa)
     55         {
     56             getroot(e[k].to,u);
     57             sz[u]+=sz[e[k].to];
     58             fx[u]=max(fx[u],sz[e[k].to]);
     59         }
     60     fx[u]=max(fx[u],sum-sz[u]);
     61     if(fx[u]<fx[root])    root=u;
     62 }
     63 void getsz(int u,int fa)
     64 {
     65     sz[u]=1;
     66     for(int k=f1[u];k;k=e[k].nxt)
     67         if(!vis[e[k].to]&&e[k].to!=fa)
     68         {
     69             getsz(e[k].to,u);
     70             sz[u]+=sz[e[k].to];
     71         }
     72 }
     73 void getdeep(int u,int fa)
     74 {
     75     s[root].insert(getdis(u,ff[root]));
     76     for(int k=f1[u];k;k=e[k].nxt)
     77         if(!vis[e[k].to]&&e[k].to!=fa)
     78             getdeep(e[k].to,u);
     79 }
     80 char tmp[20];
     81 int getmax2(int p)
     82 {
     83     if(s2[p].size()<2)    return -0x3f3f3f3f;
     84     int t1=s2[p].top();s2[p].pop();int t2=s2[p].top();s2[p].insert(t1);
     85     return t1+t2;
     86 }
     87 void solve(int u)
     88 {
     89     vis[u]=1;
     90     s2[u].insert(0);
     91     for(int k=f1[u];k;k=e[k].nxt)
     92         if(!vis[e[k].to])
     93         {
     94             getsz(e[k].to,0);sum=sz[e[k].to];
     95             root=0;getroot(e[k].to,0);
     96             ff[root]=u;getdeep(root,0);
     97             if(!s[root].empty())    s2[u].insert(s[root].top());
     98             solve(root);
     99         }
    100     s3.insert(getmax2(u));
    101 }
    102 void dfs1(int u,int fa,int d,int d2)
    103 {
    104     eu[++eu[0]]=u;pos[u]=eu[0];dpx[eu[0]]=d;dpx2[eu[0]]=d2;
    105     for(int k=f1[u];k;k=e[k].nxt)
    106         if(e[k].to!=fa)
    107         {
    108             dfs1(e[k].to,u,d+1,d2+e[k].d);
    109             eu[++eu[0]]=u;
    110             dpx[eu[0]]=d;
    111             dpx2[eu[0]]=d2;
    112         }
    113 }
    114 //void debugxxxx(multiset<int>& s)
    115 //{
    116 //    for(auto i : s)    printf("%d ",i);
    117 //    puts("test");
    118 //}
    119 void change(int u)
    120 {
    121     int now;
    122     s3.erase(getmax2(u));
    123     if(!fl[u])    s2[u].erase(0);
    124     for(now=u;ff[now];now=ff[now])
    125     {
    126         s3.erase(getmax2(ff[now]));
    127         if(!s[now].empty())    s2[ff[now]].erase(s[now].top());
    128         if(!fl[u])    s[now].erase(getdis(u,ff[now]));
    129     }
    130     fl[u]^=1;
    131     if(!fl[u])    s2[u].insert(0);
    132     s3.insert(getmax2(u));
    133     for(now=u;ff[now];now=ff[now])
    134     {
    135         if(!fl[u])    s[now].insert(getdis(u,ff[now]));
    136         if(!s[now].empty())    s2[ff[now]].insert(s[now].top());
    137         s3.insert(getmax2(ff[now]));
    138     }
    139 }
    140 int num;
    141 int main()
    142 {
    143     lft[0]=1;
    144     fx[0]=0x3f3f3f3f;
    145     int i,j,a,b,la=0,q,t,c;
    146     for(i=1;i<=27;i++)    lft[i]=(lft[i-1]<<1);
    147     for(i=1;i<=200000;i++)
    148     {
    149         if(i>=lft[la+1])    ++la;
    150         log2x[i]=la;
    151     }
    152     scanf("%d",&n);
    153     for(i=1;i<n;i++)
    154     {
    155         scanf("%d%d%d",&a,&b,&c);
    156         e[++ne].to=b;e[ne].nxt=f1[a];e[ne].d=c;f1[a]=ne;
    157         e[++ne].to=a;e[ne].nxt=f1[b];e[ne].d=c;f1[b]=ne;
    158     }
    159     dfs1(1,0,0,0);
    160     for(i=1;i<=eu[0];i++)    st[i][0]=eu[i];
    161     for(j=1;(1<<j)<=eu[0];j++)
    162         for(i=1;i+lft[j]-1<=eu[0];i++)
    163             if(dpx[pos[st[i][j-1]]]>dpx[pos[st[i+lft[j-1]][j-1]]])
    164                 st[i][j]=st[i+lft[j-1]][j-1];
    165             else
    166                 st[i][j]=st[i][j-1];
    167     sum=n;getroot(1,0);
    168     solve(root);
    169     scanf("%d",&q);
    170     num=n;
    171     while(q--)
    172     {
    173         scanf("%s",tmp);
    174         if(tmp[0]=='A')
    175         {
    176             if(num==0)    printf("They have disappeared.
    ");
    177             else if(num==1)    printf("0
    ");
    178             else    printf("%d
    ",max(s3.top(),0));
    179         }
    180         else if(tmp[0]=='C')
    181         {
    182             scanf("%d",&t);
    183             if(fl[t])    num++;else    num--;
    184             change(t);
    185         }
    186     }
    187     return 0;
    188 }
    View Code

    upd20181231:

    用网上的链分治做法重写了,果然常数小很多,可以A了,然而代码量似乎更大

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<queue>
      6 using namespace std;
      7 #define fi first
      8 #define se second
      9 #define mp make_pair
     10 #define pb push_back
     11 typedef long long ll;
     12 typedef unsigned long long ull;
     13 typedef pair<int,int> pii;
     14 struct E
     15 {
     16     int to,nxt,d;
     17 }e[200011];
     18 int f1[100011],ne;
     19 const int inf1=0x3f3f3f3f;
     20 struct Set
     21 {
     22     priority_queue<int> s,t;int sz;
     23     void push(int x){s.push(x);++sz;}
     24     void erase(int x){t.push(x);--sz;}
     25     int top()
     26     {
     27         while(s.size()&&t.size()&&s.top()==t.top())
     28             s.pop(),t.pop();
     29         return sz?s.top():-inf1;
     30     }
     31     int sum2()//最大2个之和
     32     {
     33         if(sz<2)    return 0;
     34         int a1=top();erase(a1);
     35         int a2=top();push(a1);
     36         return a1+a2;
     37     }
     38 }q[100011],&q0=q[0];
     39 int d[100011];
     40 struct I
     41 {
     42     int da,db,d;
     43     //a表示向下最长轻链,d表示到1距离;max{a+d},max{a-d},max{ar+al+dr-dl}
     44 };
     45 void merge(I &c,const I &a,const I &b)
     46 {
     47     c.da=max(a.da,b.da);
     48     c.db=max(a.db,b.db);
     49     c.d=max(max(a.d,b.d),b.da+a.db);
     50 }
     51 namespace S
     52 {
     53     struct D
     54     {
     55         int lc,rc;I d;
     56     }g[1000011];
     57     int mem;
     58 #define LC g[u].lc
     59 #define RC g[u].rc
     60     void upd(int u){merge(g[u].d,g[LC].d,g[RC].d);}
     61     I x;int L;
     62     /*
     63     void init()
     64     {
     65         g[0].d.da=g[0].d.db=g[0].d.d=-inf1;
     66     }
     67     inline int gnode()
     68     {
     69         int t=++mem;
     70         g[t].d.da=g[t].d.db=g[t].d.d=g[t].d.a=-inf1;
     71         return t;
     72     }
     73     */
     74     void _setx(int l,int r,int &u)
     75     {
     76         if(!u)    u=++mem;
     77         if(l==r)
     78         {
     79             g[u].d=x;
     80             return;
     81         }
     82         int mid=(l+r)>>1;
     83         if(L<=mid)    _setx(l,mid,LC);
     84         else    _setx(mid+1,r,RC);
     85         upd(u);
     86     }
     87     I getx(int L,int R,int l,int r,int u)
     88     {
     89         if(L<=l&&r<=R)    return g[u].d;
     90         int mid=(l+r)>>1;
     91         if(L<=mid&&mid<R)
     92         {
     93             I t;merge(t,getx(L,R,l,mid,LC),getx(L,R,mid+1,r,RC));
     94             return t;
     95         }
     96         else if(L<=mid)
     97             return getx(L,R,l,mid,LC);
     98         else if(mid<R)
     99             return getx(L,R,mid+1,r,RC);
    100     }
    101 }
    102 int dep[100011],sz[100011];
    103 int d2[100011],hson[100011];
    104 int ff[100011];
    105 void dfs1(int u,int fa)
    106 {
    107     sz[u]=1;
    108     int v;
    109     for(int k=f1[u];k;k=e[k].nxt)
    110         if(e[k].to!=fa)
    111         {
    112             v=e[k].to;
    113             ff[v]=u;
    114             dep[v]=dep[u]+1;
    115             d[v]=d[u]+e[k].d;
    116             dfs1(v,u);
    117             sz[u]+=sz[v];
    118             if(sz[v]>sz[hson[u]])    hson[u]=v;
    119         }
    120 }
    121 int b[100011],pl[100011],tp[100011],dwn[100011],len[100011];
    122 int rt[100011],oknum;
    123 bool ok[100011];
    124 int n,m;
    125 void dfs2(int u,int fa)
    126 {
    127     ok[u]=1;q[u].push(0);
    128     b[++b[0]]=u;pl[u]=b[0];
    129     tp[u]=(u==hson[fa])?tp[fa]:u;
    130     if(hson[u])    dfs2(hson[u],u);
    131     dwn[u]=hson[u]?dwn[hson[u]]:u;
    132     len[u]=dep[dwn[u]]-dep[tp[u]]+1;
    133     int v,k;
    134     for(k=f1[u];k;k=e[k].nxt)
    135         if(e[k].to!=fa&&e[k].to!=hson[u])
    136         {
    137             v=e[k].to;
    138             dfs2(v,u);
    139             q[u].push(d2[v]-d[u]);
    140         }
    141     {
    142         int t=q[u].top();
    143         using namespace S;
    144         x.da=t+d[u];x.db=t-d[u];x.d=q[u].sum2();
    145         L=dep[u]-dep[tp[u]]+1;_setx(1,len[u],rt[tp[u]]);
    146     }
    147     if(u==tp[u])
    148     {
    149         const I &t=S::g[rt[u]].d;
    150         d2[u]=t.da;
    151         q0.push(t.d);
    152     }
    153 }
    154 int main()
    155 {
    156     int i,x,y,z,t,u,v;
    157     char tmp[233];
    158     //S::init();
    159     scanf("%d",&n);
    160     for(i=1;i<n;++i)
    161     {
    162         scanf("%d%d%d",&x,&y,&z);
    163         e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;e[ne].d=z;
    164         e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;e[ne].d=z;
    165     }
    166     dfs1(1,0);
    167     oknum=n;
    168     dfs2(1,0);
    169     //printf("%d
    ",q0.top());
    170     scanf("%d",&m);
    171     while(m--)
    172     {
    173         scanf("%s",tmp);
    174         if(tmp[0]=='C')
    175         {
    176             scanf("%d",&u);
    177             if(ok[u])
    178             {
    179                 --oknum;
    180                 q[u].erase(0);
    181             }
    182             else
    183             {
    184                 ++oknum;
    185                 q[u].push(0);
    186             }
    187             ok[u]^=1;
    188             while(u)
    189             {
    190                 q0.erase(S::g[rt[tp[u]]].d.d);
    191                 {
    192                     t=q[u].top();
    193                     using namespace S;I &x=S::x;
    194                     x.da=t+d[u];x.db=t-d[u];x.d=q[u].sum2();
    195                     L=dep[u]-dep[tp[u]]+1;_setx(1,len[u],rt[tp[u]]);
    196                 }
    197                 u=tp[u];v=ff[u];
    198                 const I &t=S::g[rt[u]].d;
    199                 if(v)    q[v].erase(d2[u]-d[v]);
    200                 d2[u]=t.da;
    201                 if(v)    q[v].push(d2[u]-d[v]);
    202                 q0.push(t.d);
    203                 u=v;
    204             }
    205         }
    206         else
    207         {
    208             if(!oknum)
    209             {
    210                 puts("They have disappeared.");
    211                 continue;
    212             }
    213             printf("%d
    ",q0.top());
    214         }
    215     }
    216     return 0;
    217 }
    View Code
  • 相关阅读:
    在线学习git操作
    logstash使用ruby 修改事件戳时间
    mysql磁盘问题记录
    mkdir --help
    php过滤前端post提交过滤html标签
    【摸鱼范式】【一】UVM入门教程【文字版】
    第一次运行svlib
    svlib文档翻译(第五章)
    svlib文档翻译(第一至四章)
    【三】基于Montgomery算法的高速、可配置RSA密码IP核硬件设计系列
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9285659.html
Copyright © 2020-2023  润新知