这可能是全场最长的一份代码
问的其实是对于关键点的斯坦纳树大小
考虑补集转化,不合法的点就是它的子树中没有关键点的点和斯坦纳树根的祖先
树根不难求,关键点中dfs序最大最小点的LCA就是了
问题在前者
假如我们把子树中的点拿出来排序,这个点不合法的条件就是存在ax,ax+1满足ax<=l-1且r+1<=ax+1,有个很妙的性质就是这个合法的x只有1个
考虑启发式合并把这个顺序搞出来,可以证明点数是nlogn级别的,因为每次合并均摊加入logn个点,合并n次。数列相邻的两项成为一个点,插入要用到一棵splay来维护一下。。。
把这些点放到二维平面二维数点即可。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int _=1e2; const int maxn=1e5+_; const int maxQ=5e5+_; const int mbit=30; const int fbin=(1<<17)+_; int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } void write(int x) { if(x>=10)write(x/10); putchar(x%10+'0'); } int n,Q; struct node { int x,y,next; }a[2*maxn];int len,last[maxn],d[maxn]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } //--------------------------------------------def------------------------------------------------------- namespace TREE { namespace Segtree { struct segtree{int mx,mn;segtree(){mn=(1<<30);}}tr[2*fbin]; void update(int now) { int lc=(now<<1),rc=(now<<1|1); tr[now].mx=max(tr[lc].mx,tr[rc].mx); tr[now].mn=min(tr[lc].mn,tr[rc].mn); } void pushdown(int now) { int lc=(now<<1),rc=(now<<1|1); tr[lc].mx=max(tr[now].mx,tr[lc].mx); tr[rc].mn=min(tr[now].mn,tr[rc].mn); } void change(int now,int ql,int qr,int p,int k) { if(ql==qr) { tr[now].mx=max(tr[now].mx,k); tr[now].mn=min(tr[now].mn,k); return ; } int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2; pushdown(now); if(p<=mid)change(lc,ql,mid,p,k); else change(rc,mid+1,qr,p,k); update(now); } int getmax(int now,int ql,int qr,int l,int r) { if(ql==l&&qr==r)return tr[now].mx; int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2; pushdown(now); if(r<=mid) return getmax(lc,ql,mid,l,r); else if(mid+1<=l)return getmax(rc,mid+1,qr,l,r); else return max(getmax(lc,ql,mid,l,mid),getmax(rc,mid+1,qr,mid+1,r)); } int getmin(int now,int ql,int qr,int l,int r) { if(ql==l&&qr==r)return tr[now].mn; int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2; pushdown(now); if(r<=mid) return getmin(lc,ql,mid,l,r); else if(mid+1<=l)return getmin(rc,mid+1,qr,l,r); else return min(getmin(lc,ql,mid,l,mid),getmin(rc,mid+1,qr,mid+1,r)); } } //~~~~~~~~~~~~~~getnum~~~~~~~~~~~~~~~~~ int z,pos[maxn]; int dep[maxn],fa[mbit][maxn]; void dfs(int x,int fr) { pos[++z]=x; Segtree::change(1,1,n,d[x],z); for(int i=1;(1<<i)<=dep[x];i++)fa[i][x]=fa[i-1][fa[i-1][x]]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=fa[0][x]) { fa[0][y]=x; dep[y]=dep[x]+1; dfs(y,x); } } } int LCA(int x,int y) { if(dep[x]<dep[y])swap(x,y); for(int i=25;i>=0;i--) if(dep[x]-dep[y]>=(1<<i))x=fa[i][x]; if(x==y)return x; for(int i=25;i>=0;i--) if(dep[x]>=(1<<i)&&fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y]; return fa[0][x]; } int getnum(int l,int r) { return dep[LCA(pos[Segtree::getmax(1,1,n,l,r)],pos[Segtree::getmin(1,1,n,l,r)])]; } //~~~~~~~~~~~~~~~make~~~~~~~~~~~~~~~~~ int ls[maxn],id[maxn]; bool cmp(int x,int y){return d[x]<d[y];} int getl(int l){return lower_bound(ls+1,ls+n+1,l)-ls;} int getr(int r){return upper_bound(ls+1,ls+n+1,r)-ls-1;} void LSH() { for(int i=1;i<=n;i++)ls[i]=d[i],id[i]=i; sort(ls+1,ls+n+1); sort(id+1,id+n+1,cmp); for(int i=1;i<=n;i++)d[id[i]]=i; } //~~~~~~~~~~~~~~~~LSH~~~~~~~~~~~~~~~~ void main(){LSH();dfs(1,0);} } //-------------------------------------------------------------------------------------------- namespace COUNT { namespace Chair { struct chairmantree { int lc,rc,c; }tr[100*maxn];int trlen,rt[maxn]; int insert(int x,int ql,int qr,int p,int c) { if(x==0)x=++trlen; tr[x].c+=c; if(ql==qr)return x; int mid=(ql+qr)/2; if(p<=mid)tr[x].lc=insert(tr[x].lc,ql,mid,p,c); else tr[x].rc=insert(tr[x].rc,mid+1,qr,p,c); return x; } int merge(int x,int y) { if(x==0||y==0)return x+y; tr[x].c+=tr[y].c; tr[x].lc=merge(tr[x].lc,tr[y].lc); tr[x].rc=merge(tr[x].rc,tr[y].rc); return x; } int getsum(int now,int ql,int qr,int l,int r) { if(ql==l&&qr==r){return tr[now].c;} int lc=tr[now].lc,rc=tr[now].rc,mid=(ql+qr)/2; if(r<=mid) return getsum(lc,ql,mid,l,r); else if(mid+1<=l)return getsum(rc,mid+1,qr,l,r); else return getsum(lc,ql,mid,l,mid)+getsum(rc,mid+1,qr,mid+1,r); } void newid(int &x,int &y){x++,y=n+1-y+1;} void paint(int x,int y,int c) { newid(x,y); rt[x]=insert(rt[x],1,n+1,y,c); } int getnum(int x,int y) { newid(x,y); return getsum(rt[x],1,n+1,1,y); } void pre() { for(int i=1;i<=n+1;i++) rt[i]=merge(rt[i],rt[i-1]); } } namespace Splay { struct splay { int f,son[2]; int q,x,c,lazy; }tr[30*maxn];int trlen,rt[maxn],tot[maxn],id[2*30*maxn],idtp; void init(){for(int i=1;i<30*maxn;i++)id[i]=i;idtp=30*maxn;} void tap(int w){tr[rt[w]].c++,tr[rt[w]].lazy++;} void rotate(int x,int w) { int f=tr[x].f,ff=tr[f].f; int R,r; R=f,r=tr[x].son[w]; tr[R].son[1-w]=r; if(r!=0)tr[r].f=R; R=ff,r=x; if(tr[ff].son[0]==f)tr[R].son[0]=r; else tr[R].son[1]=r; tr[r].f=R; R=x,r=f; tr[R].son[w]=r; tr[r].f=R; } void pushdown(int now) { int lc=tr[now].son[0],rc=tr[now].son[1]; tr[lc].c+=tr[now].lazy,tr[lc].lazy+=tr[now].lazy; tr[rc].c+=tr[now].lazy,tr[rc].lazy+=tr[now].lazy; tr[now].lazy=0; } int tt,tmp[maxn]; void splay(int x,int F,int w) { int i=x; tt=0; while(i!=F) tmp[++tt]=i,i=tr[i].f; while(tt>0) { if(tr[tmp[tt]].lazy!=0)pushdown(tmp[tt]); tt--; } while(tr[x].f!=F) { int f=tr[x].f,ff=tr[f].f; if(ff==F) { if(tr[f].son[0]==x)rotate(x,1); else rotate(x,0); } else { if(tr[ff].son[0]==f&&tr[f].son[0]==x)rotate(f,1),rotate(x,1); else if(tr[ff].son[1]==f&&tr[f].son[1]==x)rotate(f,0),rotate(x,0); else if(tr[ff].son[0]==f&&tr[f].son[1]==x)rotate(x,0),rotate(x,1); else if(tr[ff].son[1]==f&&tr[f].son[0]==x)rotate(x,1),rotate(x,0); } } if(F==0)rt[w]=x; } //~~~~~~~~~~~~~~~~~~~~in~~~~~~~~~~~~~~~~~~~~~~ int findip(int w,int d) { int x=rt[w]; while(1) { pushdown(x); int lc=tr[x].son[0],rc=tr[x].son[1]; if(d<tr[x].x) { if(lc==0)return x; x=lc; } else { if(rc==0)return x; x=rc; } } } int findqq(int x,int w) { splay(x,0,w); x=tr[x].son[0]; while(tr[x].son[1]!=0)x=tr[x].son[1]; return x; } int findhj(int x,int w) { splay(x,0,w); x=tr[x].son[1]; while(tr[x].son[0]!=0)x=tr[x].son[0]; return x; } //~~~~~~~~~~~~~~~~~~~find~~~~~~~~~~~~~~~~~~~~~~ void add(int x) { trlen++; if(trlen==2*30*maxn)trlen=1; tr[id[trlen]].x=x; tr[id[trlen]].c=0,tr[id[trlen]].lazy=0; } void insert(int w,int d) { tot[w]++;add(d); if(rt[w]==0)rt[w]=id[trlen]; else if(tot[w]==2) { tr[rt[w]].son[1]=id[trlen]; tr[id[trlen]].f=rt[w]; tr[id[trlen]].q=0; } else { int p=findip(w,d); if(d<tr[p].x)tr[p].son[0]=id[trlen]; else tr[p].son[1]=id[trlen]; tr[id[trlen]].f=p; tr[id[trlen]].q=tr[findqq(id[trlen],w)].x; int h=findhj(id[trlen],w);splay(h,0,w); if(tr[h].c!=0)Chair::paint(tr[h].q,tr[h].x,tr[h].c),tr[h].c=0; tr[h].q=tr[id[trlen]].x; } } //~~~~~~~~~~~~~~~~~base~~~~~~~~~~~~~~~~~~~~~~~~ void dfs(int w,int x) { if(tr[x].c!=0&&tr[x].x!=0)Chair::paint(tr[x].q,tr[x].x,tr[x].c); if(tr[x].x!=0&&tr[x].x!=n+1) { insert(w,tr[x].x); id[idtp++]=x; if(idtp==2*30*maxn)idtp=1; } pushdown(x); if(tr[x].son[0]!=0)dfs(w,tr[x].son[0]); if(tr[x].son[1]!=0)dfs(w,tr[x].son[1]); } void merge(int x,int y) { if(tot[x]<tot[y])swap(rt[x],rt[y]),swap(tot[x],tot[y]); dfs(x,rt[y]); } void dfs2(int x) { if(tr[x].c!=0&&tr[x].x!=0)Chair::paint(tr[x].q,tr[x].x,tr[x].c); pushdown(x); if(tr[x].son[0]!=0)dfs2(tr[x].son[0]); if(tr[x].son[1]!=0)dfs2(tr[x].son[1]); } void divi(){dfs2(rt[1]);} } void dfs(int x,int fr) { for(int k=last[x];k;k=a[k].next) if(a[k].y!=fr)dfs(a[k].y,x); Splay::insert(x,0); Splay::insert(x,n+1); Splay::insert(x,d[x]); for(int k=last[x];k;k=a[k].next) if(a[k].y!=fr)Splay::merge(x,a[k].y); Splay::tap(x); } void main() { Splay::init();dfs(1,0); Splay::divi(); Chair::pre(); } } //-------------------------------------------------------------------------------------------- namespace QUERY { void main() { int l,r; while(Q--) { l=read(),r=read(); l=TREE::getl(l); r=TREE::getr(r); if(l>r)puts("0"); else write(n- (TREE::getnum(l,r)) - (COUNT::Chair::getnum(l-1,r+1)) ),putchar(' '); } } } //-------------------------------------------------------------------------------------------- int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int x,y; n=read(),Q=read(); for(int i=1;i<=n;i++)d[i]=read(); for(int i=1;i<n;i++) { x=read(),y=read(); ins(x,y),ins(y,x); } TREE::main(); COUNT::main(); QUERY::main(); return 0; }
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int _=1e2; const int maxn=1e5+_; const int maxQ=5e5+_; const int mbit=30; const int fbin=(1<<17)+_; int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } void write(int x) { if(x>=10)write(x/10); putchar(x%10+'0'); } int n,Q; struct node { int x,y,next; }a[2*maxn];int len,last[maxn],d[maxn]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } //--------------------------------------------def------------------------------------------------------- namespace TREE { namespace Segtree { struct segtree{int mx,mn;segtree(){mn=(1<<30);}}tr[2*fbin]; void update(int now) { int lc=(now<<1),rc=(now<<1|1); tr[now].mx=max(tr[lc].mx,tr[rc].mx); tr[now].mn=min(tr[lc].mn,tr[rc].mn); } void pushdown(int now) { int lc=(now<<1),rc=(now<<1|1); tr[lc].mx=max(tr[now].mx,tr[lc].mx); tr[rc].mn=min(tr[now].mn,tr[rc].mn); } void change(int now,int ql,int qr,int p,int k) { if(ql==qr) { tr[now].mx=max(tr[now].mx,k); tr[now].mn=min(tr[now].mn,k); return ; } int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2; pushdown(now); if(p<=mid)change(lc,ql,mid,p,k); else change(rc,mid+1,qr,p,k); update(now); } int getmax(int now,int ql,int qr,int l,int r) { if(ql==l&&qr==r)return tr[now].mx; int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2; pushdown(now); if(r<=mid) return getmax(lc,ql,mid,l,r); else if(mid+1<=l)return getmax(rc,mid+1,qr,l,r); else return max(getmax(lc,ql,mid,l,mid),getmax(rc,mid+1,qr,mid+1,r)); } int getmin(int now,int ql,int qr,int l,int r) { if(ql==l&&qr==r)return tr[now].mn; int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2; pushdown(now); if(r<=mid) return getmin(lc,ql,mid,l,r); else if(mid+1<=l)return getmin(rc,mid+1,qr,l,r); else return min(getmin(lc,ql,mid,l,mid),getmin(rc,mid+1,qr,mid+1,r)); } } //~~~~~~~~~~~~~~getnum~~~~~~~~~~~~~~~~~ int z,pos[maxn]; int dep[maxn],fa[mbit][maxn]; void dfs(int x,int fr) { pos[++z]=x; Segtree::change(1,1,n,d[x],z); for(int i=1;(1<<i)<=dep[x];i++)fa[i][x]=fa[i-1][fa[i-1][x]]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=fa[0][x]) { fa[0][y]=x; dep[y]=dep[x]+1; dfs(y,x); } } } int LCA(int x,int y) { if(dep[x]<dep[y])swap(x,y); for(int i=25;i>=0;i--) if(dep[x]-dep[y]>=(1<<i))x=fa[i][x]; if(x==y)return x; for(int i=25;i>=0;i--) if(dep[x]>=(1<<i)&&fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y]; return fa[0][x]; } int getnum(int l,int r) { return dep[LCA(pos[Segtree::getmax(1,1,n,l,r)],pos[Segtree::getmin(1,1,n,l,r)])]; } //~~~~~~~~~~~~~~~make~~~~~~~~~~~~~~~~~ int ls[maxn],id[maxn]; bool cmp(int x,int y){return d[x]<d[y];} int getl(int l){return lower_bound(ls+1,ls+n+1,l)-ls;} int getr(int r){return upper_bound(ls+1,ls+n+1,r)-ls-1;} void LSH() { for(int i=1;i<=n;i++)ls[i]=d[i],id[i]=i; sort(ls+1,ls+n+1); sort(id+1,id+n+1,cmp); for(int i=1;i<=n;i++)d[id[i]]=i; } //~~~~~~~~~~~~~~~~LSH~~~~~~~~~~~~~~~~ void main(){LSH();dfs(1,0);} } //-------------------------------------------------------------------------------------------- namespace COUNT { namespace Chair { struct chairmantree { int lc,rc,c; }tr[100*maxn];int trlen,rt[maxn]; int insert(int x,int ql,int qr,int p,int c) { if(x==0)x=++trlen; tr[x].c+=c; if(ql==qr)return x; int mid=(ql+qr)/2; if(p<=mid)tr[x].lc=insert(tr[x].lc,ql,mid,p,c); else tr[x].rc=insert(tr[x].rc,mid+1,qr,p,c); return x; } int merge(int x,int y) { if(x==0||y==0)return x+y; tr[x].c+=tr[y].c; tr[x].lc=merge(tr[x].lc,tr[y].lc); tr[x].rc=merge(tr[x].rc,tr[y].rc); return x; } int getsum(int now,int ql,int qr,int l,int r) { if(ql==l&&qr==r){return tr[now].c;} int lc=tr[now].lc,rc=tr[now].rc,mid=(ql+qr)/2; if(r<=mid) return getsum(lc,ql,mid,l,r); else if(mid+1<=l)return getsum(rc,mid+1,qr,l,r); else return getsum(lc,ql,mid,l,mid)+getsum(rc,mid+1,qr,mid+1,r); } void newid(int &x,int &y){x++,y=n+1-y+1;} void paint(int x,int y,int c) { newid(x,y); rt[x]=insert(rt[x],1,n+1,y,c); } int getnum(int x,int y) { newid(x,y); return getsum(rt[x],1,n+1,1,y); } void pre() { for(int i=1;i<=n+1;i++) rt[i]=merge(rt[i],rt[i-1]); } } namespace Splay { struct splay { int f,son[2]; int q,x,c,lazy; }tr[30*maxn];int trlen,rt[maxn],tot[maxn],id[2*30*maxn],idtp; void init(){for(int i=1;i<30*maxn;i++)id[i]=i;idtp=30*maxn;} void tap(int w){tr[rt[w]].c++,tr[rt[w]].lazy++;} void rotate(int x,int w) { int f=tr[x].f,ff=tr[f].f; int R,r; R=f,r=tr[x].son[w]; tr[R].son[1-w]=r; if(r!=0)tr[r].f=R; R=ff,r=x; if(tr[ff].son[0]==f)tr[R].son[0]=r; else tr[R].son[1]=r; tr[r].f=R; R=x,r=f; tr[R].son[w]=r; tr[r].f=R; } void pushdown(int now) { int lc=tr[now].son[0],rc=tr[now].son[1]; tr[lc].c+=tr[now].lazy,tr[lc].lazy+=tr[now].lazy; tr[rc].c+=tr[now].lazy,tr[rc].lazy+=tr[now].lazy; tr[now].lazy=0; } int tt,tmp[maxn]; void splay(int x,int F,int w) { int i=x; tt=0; while(i!=F) tmp[++tt]=i,i=tr[i].f; while(tt>0) { if(tr[tmp[tt]].lazy!=0)pushdown(tmp[tt]); tt--; } while(tr[x].f!=F) { int f=tr[x].f,ff=tr[f].f; if(ff==F) { if(tr[f].son[0]==x)rotate(x,1); else rotate(x,0); } else { if(tr[ff].son[0]==f&&tr[f].son[0]==x)rotate(f,1),rotate(x,1); else if(tr[ff].son[1]==f&&tr[f].son[1]==x)rotate(f,0),rotate(x,0); else if(tr[ff].son[0]==f&&tr[f].son[1]==x)rotate(x,0),rotate(x,1); else if(tr[ff].son[1]==f&&tr[f].son[0]==x)rotate(x,1),rotate(x,0); } } if(F==0)rt[w]=x; } //~~~~~~~~~~~~~~~~~~~~in~~~~~~~~~~~~~~~~~~~~~~ int findip(int w,int d) { int x=rt[w]; while(1) { pushdown(x); int lc=tr[x].son[0],rc=tr[x].son[1]; if(d<tr[x].x) { if(lc==0)return x; x=lc; } else { if(rc==0)return x; x=rc; } } } int findqq(int x,int w) { splay(x,0,w); x=tr[x].son[0]; while(tr[x].son[1]!=0)x=tr[x].son[1]; return x; } int findhj(int x,int w) { splay(x,0,w); x=tr[x].son[1]; while(tr[x].son[0]!=0)x=tr[x].son[0]; return x; } //~~~~~~~~~~~~~~~~~~~find~~~~~~~~~~~~~~~~~~~~~~ void add(int x) { trlen++; if(trlen==2*30*maxn)trlen=1; tr[id[trlen]].x=x; tr[id[trlen]].c=0,tr[id[trlen]].lazy=0; } void insert(int w,int d) { tot[w]++;add(d); if(rt[w]==0)rt[w]=id[trlen]; else if(tot[w]==2) { tr[rt[w]].son[1]=id[trlen]; tr[id[trlen]].f=rt[w]; tr[id[trlen]].q=0; } else { int p=findip(w,d); if(d<tr[p].x)tr[p].son[0]=id[trlen]; else tr[p].son[1]=id[trlen]; tr[id[trlen]].f=p; tr[id[trlen]].q=tr[findqq(id[trlen],w)].x; int h=findhj(id[trlen],w);splay(h,0,w); if(tr[h].c!=0)Chair::paint(tr[h].q,tr[h].x,tr[h].c),tr[h].c=0; tr[h].q=tr[id[trlen]].x; } } //~~~~~~~~~~~~~~~~~base~~~~~~~~~~~~~~~~~~~~~~~~ void dfs(int w,int x) { if(tr[x].c!=0&&tr[x].x!=0)Chair::paint(tr[x].q,tr[x].x,tr[x].c); if(tr[x].x!=0&&tr[x].x!=n+1) { insert(w,tr[x].x); id[idtp++]=x; if(idtp==2*30*maxn)idtp=1; } pushdown(x); if(tr[x].son[0]!=0)dfs(w,tr[x].son[0]); if(tr[x].son[1]!=0)dfs(w,tr[x].son[1]); } void merge(int x,int y) { if(tot[x]<tot[y])swap(rt[x],rt[y]),swap(tot[x],tot[y]); dfs(x,rt[y]); } void dfs2(int x) { if(tr[x].c!=0&&tr[x].x!=0)Chair::paint(tr[x].q,tr[x].x,tr[x].c); pushdown(x); if(tr[x].son[0]!=0)dfs2(tr[x].son[0]); if(tr[x].son[1]!=0)dfs2(tr[x].son[1]); } void divi(){dfs2(rt[1]);} } void dfs(int x,int fr) { for(int k=last[x];k;k=a[k].next) if(a[k].y!=fr)dfs(a[k].y,x); Splay::insert(x,0); Splay::insert(x,n+1); Splay::insert(x,d[x]); for(int k=last[x];k;k=a[k].next) if(a[k].y!=fr)Splay::merge(x,a[k].y); Splay::tap(x); } void main() { Splay::init();dfs(1,0); Splay::divi(); Chair::pre(); } } //-------------------------------------------------------------------------------------------- namespace QUERY { void main() { int l,r; while(Q--) { l=read(),r=read(); l=TREE::getl(l); r=TREE::getr(r); if(l>r)puts("0"); else write(n- (TREE::getnum(l,r)) - (COUNT::Chair::getnum(l-1,r+1)) ),putchar(' '); } } } //-------------------------------------------------------------------------------------------- int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int x,y; n=read(),Q=read(); for(int i=1;i<=n;i++)d[i]=read(); for(int i=1;i<n;i++) { x=read(),y=read(); ins(x,y),ins(y,x); } TREE::main(); COUNT::main(); QUERY::main(); return 0; }