Query on a tree IV SPOJ - QTREE4

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.\n");
177             else if(num==1)    printf("0\n");
178             else    printf("%d\n",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 }

猜你喜欢

转载自www.cnblogs.com/hehe54321/p/9285659.html