点分治还能这么用,感觉好妙啊
然而我不到200行的程序居然错了10多个地方,调了一晚上,简直zz
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define R register
using namespace std;
typedef long long LL;
inline int read()
{
int x=0;bool f=0;char c=getchar();
for (;c<'0'||c>'9';c=getchar()) f=c=='-'?1:0;
for (;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
return f?-x:x;
}
const int N=500005,P=998244353,S=10;
int n,m,p,q,sn[N],br[N],fa[N],dis[N],xi[N],yi[N],seq[N],sq,
hd[N],nxt[N],xq[N],yq[N],lim[N],
rt,siz,sz[N],s2[N],pth[N],pc;
LL ans[N];
bool vis[N],inp[N];
struct na {int a,x,y,id;}e[N],e2[N],*pt,*pt2;
inline bool cmp(const na &a,const na &b){
return (LL)a.x*b.y<(LL)a.y*b.x;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
inline bool cmp2(const na &a,const na &b){
if (a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
struct cvx{
int n,p,x[N],y[N];
inline bool cal(int x,int y,int x1,int y1,int x2,int y2){
x1-=x,x2-=x,y1-=y,y2-=y;
return (LL)x1*y2-(LL)x2*y1>=0;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
inline void insert(int a,int b){
while (n>1&&cal(x[n-1],y[n-1],x[n],y[n],a,b)) n--;
x[++n]=a,y[n]=b;
}
inline LL calc(int a,int b){
LL rec=(LL)x[p]*a+(LL)y[p]*b,r2;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
while (p<n){
r2=(LL)x[p+1]*a+(LL)y[p+1]*b;
if (r2>rec) rec=r2,p++;
else break;
}
return rec;
}
}cv;
void solve(int l,int r,int a,int b)
{
if (r-l<S||b-a<S) {
for (R int i=a;i<=b;i++)
for (R int j=l;j<=r;j++)
if (pt[j].a<=e[i].a)//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ans[e[i].id]=max(ans[e[i].id],(LL)e[i].x*pt[j].x +(LL)e[i].y*pt[j].y);
return;
}
cv.n=0;cv.p=1;
int mid=l+r>>1,l1=a,l2=0,p1=l,p2=0;
for (R int i=l;i<=r;i++) if (pt[i].a<=mid)
cv.insert(pt[i].x,pt[i].y);
for (R int i=a;i<=b;i++) if (e[i].a>mid)
ans[e[i].id]=max(ans[e[i].id],cv.calc(e[i].x,e[i].y));
for (R int i=a;i<=b;i++)
(e[i].a<=mid)?e[l1++]=e[i]:e2[++l2]=e[i];
for (R int i=1;i<=l2;i++) e[l1++]=e2[i];
for (R int i=l;i<=r;i++)
(pt[i].a<=mid)?pt[p1++]=pt[i]:pt2[++p2]=pt[i];
for (R int i=1;i<=p2;i++) pt[p1++]=pt2[i];
solve(l,r-p2,a,b-l2);
solve(r-p2+1,r,b-l2+1,b);
}
void dfs_root(int u,int f)
{
sz[u]=1;s2[u]=0;
for (int v=sn[u];v;v=br[v]) if (v!=f&&!vis[v])
dfs_root(v,u),sz[u]+=sz[v],s2[u]=max(s2[u],sz[v]);
if (fa[u]!=f&&!vis[fa[u]]) dfs_root(fa[u],u),sz[u]+=sz[fa[u]],s2[u]=max(s2[u],sz[fa[u]]);
s2[u]=max(s2[u],siz-sz[u]);
if (s2[u]<s2[rt]) rt=u;
}
inline void dfs_add(int u)
{
sz[u]=1;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (u!=rt) seq[++sq]=u,inp[u]=1;
for (int i=hd[u];i;i=nxt[i])
if (!inp[lim[i]])
e[++m]=(na){min(pc,dis[rt]-dis[lim[i]]+1),xq[i],yq[i],i};
for (int v=sn[u];v;v=br[v])
if (!vis[v]) dfs_add(v),sz[u]+=sz[v];
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
void dfs(int u,int pr_siz)
{
m=pc=sq=0;
for (int p=u;!vis[p];p=fa[p]) pth[++pc]=p;
if (pth[pc]==1) pc--;
for (int i=1;i<=pc;i++) pt[i]=(na){i,xi[pth[i]],yi[pth[i]],0};
vis[u]=1;
dfs_add(u);
for (int i=1;i<=sq;i++) inp[seq[i]]=0;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (m>S&&pc>S) {
sort(e+1,e+m+1,cmp);
sort(pt+1,pt+pc+1,cmp2);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
solve(1,pc,1,m);
}
else {
for (int i=1;i<=m;i++)
for (int j=1;j<=e[i].a;j++)//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ans[e[i].id]=max(ans[e[i].id],(LL)e[i].x*pt[j].x +(LL)e[i].y*pt[j].y);
}
for (int v=sn[u];v;v=br[v]) if (!vis[v])
{
rt=0;siz=s2[0]=sz[v];
dfs_root(v,0);
dfs(rt,siz);
}
if (!vis[fa[u]])
{
rt=0;siz=s2[0]=pr_siz-sz[u];
dfs_root(fa[u],0);
dfs(rt,siz);
}
}
int main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
read();
while (m=read())
{
memset(sn,0,sizeof sn);
memset(hd,0,sizeof hd);
n=p=1;q=0;
sq=0;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
for (int i=1;i<=m;i++)
{
int op=read(),l,r;
if (op==1) {
br[++n]=sn[p],sn[p]=n,fa[n]=p,dis[n]=dis[p]+1,p=n;
seq[++sq]=p;
xi[p]=read(),yi[p]=read();
}
else if (op==2)
sq--,p=fa[p];
else {
l=read(),r=read();
lim[++q]=seq[l];
yq[q]=read(),xq[q]=-read();
nxt[q]=hd[seq[r]];hd[seq[r]]=q;
ans[q]=-5*1e18;
}
}
// pt=e+n+1,pt2=e2+n+1;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
pt=e+q+2,pt2=e2+q+2;
memset(vis,0,sizeof vis);
rt=0;s2[0]=siz=n;vis[0]=1;
dfs_root(1,0);
dfs(rt,n);
int rec=0;
for (int i=1;i<=q;i++)
rec^=(int)((ans[i]%P+P)%P);
// for (int i=1;i<=q;i++) printf("%d\n",(int)((ans[i]%P+P)%P));
printf("%d\n",rec);
}
return 0;
}