求助神秘的 UB
查看原帖
求助神秘的 UB
153687
donghanwen1225楼主2022/3/9 12:43

一开始是 WA on #11,然后把数组大小全都 +5 就成了 WA on #9,再把数组全都开到几百万就 WA on #9,#14。

不知道是什么神秘的 UB,有没有大佬帮忙找一下啊/kk

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<set>
using namespace std;
template<typename T> void Read(T &x)
{
	x=0;char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
}
int n,Q,m,op,l,r,k,rt,tot=0,ch[1000001][2],siz[1000001],rnd[1000001],t[1000001],b[1000001];
struct sz{int ind,v;}a[1000001],val[1000001];
bool cmp(sz a1,sz a2){return a1.v<a2.v;}
int lowbit(int x){return x&(-x);}
int query(int now){int res=0;for(int i=now;i;i-=lowbit(i))res+=t[i];return res;}
void modify(int now,int z){for(int i=now;i<=n;i+=lowbit(i))t[i]+=z;}
void pushup(int now){siz[now]=siz[ch[now][0]]+siz[ch[now][1]]+1;}
int newnode(sz a1)
{
	tot++;
	siz[tot]=1;
	ch[tot][0]=ch[tot][1]=0;
	rnd[tot]=rand();
	val[tot]=a1;
	return tot;
}
int merge(int x,int y)
{
	if(!x||!y) return x+y;
	if(rnd[x]<rnd[y])
	{
		ch[x][1]=merge(ch[x][1],y);
		pushup(x);
		return x;
	}
	else
	{
		ch[y][0]=merge(x,ch[y][0]);
		pushup(y);
		return y;
	}
}
void split(int now,int k,int &x,int &y)
{
	if(!now){x=y=0;return;}
	if(val[now].v<=k)
	{
		x=now;
		split(ch[now][1],k,ch[now][1],y);
	}
	else
	{
		y=now;
		split(ch[now][0],k,x,ch[now][0]);
	}
	pushup(now);
}
void del(int now)
{
	if(!now) return;
	modify(val[now].ind,1);
	del(ch[now][0]);del(ch[now][1]);
}
int build(int tl,int tr)
{
	if(tl==tr) return newnode(a[tl]);
	int mid=(tl+tr)/2;
	return merge(build(tl,mid),build(mid+1,tr));
}

int kc1,kc2,ks,Op[300005],bl[300005],L[601],R[601],ans[300005];
struct query
{
	int op,l,r,k,bh;
	friend bool operator <(const query &a1,const query &a2){return a1.k==a2.k?a1.bh<a2.bh:a1.k<a2.k;}
} q[300005];
int s1[300005],s2[300005],anc[300005];
int Find(int x){return anc[x]==x?x:anc[x]=Find(anc[x]);}
void add1(int x){s1[x]++;s2[bl[x]]++;}
int ask1(int l,int r)
{
	int pl=bl[l],pr=bl[r],res=0;
	if(pl==pr)
	{
		for(int i=l;i<=r;i++) res+=s1[i];
		return res;
	}
	for(int i=l;i<=R[pl];i++) res+=s1[i];
	for(int i=L[pr];i<=r;i++) res+=s1[i];
	for(int i=pl+1;i<=pr-1;i++) res+=s2[i];
	return res;
}
void sol1(int l,int r)
{
	for(int i=1;i<=n+1;i++) anc[i]=i;
	memset(s1,0,sizeof(s1));memset(s2,0,sizeof(s2));
	for(int i=l;i<=r;i++)
	{
		if(q[i].op==1)
		{
			int ll=lower_bound(b+1,b+1+n,q[i].l)-b,rr=upper_bound(b+1,b+1+n,q[i].r)-b-1;
			int be=Find(ll);
			while(be<=rr) add1(a[be].ind),anc[be]=anc[be+1],be=Find(be+1);
		}
		else ans[q[i].bh]=ask1(q[i].l,q[i].r);
	}
}

struct node
{
	int l,r,bh;
	node(int ll=0,int rr=0,int bhh=0){l=ll;r=rr;bh=bhh;}
	friend bool operator <(const node &a1,const node &a2){return a1.l<a2.l;}
} st[300005];
struct edge
{
	int nxt,op,l,r;
	edge(int nxtt=0,int opp=0,int ll=0,int rr=0){nxt=nxtt;op=opp;l=ll;r=rr;}
} e[1200005];
int cnt=0,top=0,h[300005],S1[300005],S2[300005];
set<node> s;
typedef set<node>::iterator iter;
void insedge(int x,int op,int l,int r){e[++cnt]=edge(h[x],op,l,r);h[x]=cnt;}
void add2(int x)
{
	for(int i=x;i<=R[bl[x]];i++) S1[i]++;
	for(int i=bl[x]+1;i<=ks;i++) S2[i]++;
}
int ask2(int x){if(!x) return 0;return S1[x]+S2[bl[x]];}
void inscz(int l,int r,int t){st[++top]=node(l,r,t);}
void ers(int l,int r,int t)
{
	for(int i=1;i<=top;i++)
		if(st[i].l==l&&st[i].r==r)
		{
			insedge(r,1,st[i].bh,t);insedge(l-1,-1,st[i].bh,t);
			for(int j=i;j<top;j++) st[j]=st[j+1];top--;
			return;
		}
}
void sol2(int ll,int rr)
{
	s.clear();top=0;
	iter il,ir;
	for(int i=ll;i<=rr;i++)
		if(q[i].op==1)
		{
			int l=lower_bound(b+1,b+1+n,q[i].l)-b,r=upper_bound(b+1,b+1+n,q[i].r)-b-1;
			if(l>r) continue;
			if(s.empty()) goto eeeen;
			il=s.lower_bound(node(l,0,0)),ir=s.upper_bound(node(r,0,0));
			if(il!=s.begin())
			{
				iter tmp=il;tmp--;
				if(tmp->r>=l) il--;
			}
			if(ir==s.begin()||(ir!=s.begin()&&(--ir)->r<l)) goto eeeen;
			l=min(l,il->l),r=max(r,ir->r);
			while(il!=ir) ers(il->l,il->r,i),il=s.erase(il);
			ers(ir->l,ir->r,i);s.erase(ir);
			eeeen:
			inscz(l,r,i);s.insert(node(l,r,i));
		}
	for(int i=1;i<=top;i++)
		insedge(st[i].r,1,st[i].bh,rr),insedge(st[i].l-1,-1,st[i].bh,rr),st[i].l=st[i].r=st[i].bh=0;
}
void sol()
{
	for(int i=1;i<=n;i++)
	{
		add2(a[i].ind);
		for(int j=h[i];j;j=e[j].nxt)
			for(int k=e[j].l;k<=e[j].r;k++)
				if(q[k].op==2) ans[q[k].bh]+=e[j].op*(ask2(q[k].r)-ask2(q[k].l-1));
	}
}
int main()
{
	Read(n);Read(Q);Read(m);
	for(int i=1;i<=n;i++)
	{
		Read(a[i].v);b[i]=a[i].v;
		a[i].ind=i;
	}
	sort(a+1,a+1+n,cmp);sort(b+1,b+1+n);
	if(m==1)
	{
	
	for(int i=1;i<=n;i++) rt=merge(rt,newnode(a[i]));
	while(Q--)
	{
		Read(op);Read(l);Read(r);Read(k);
		if(op==1)
		{
			int x,y,z;
			split(rt,l-1,x,y);
			split(y,r,y,z);
			del(y);
			rt=merge(x,z);
		}
		if(op==2) printf("%d\n",query(r)-query(l-1));
	}
	
	}
	else
	{
	
	kc1=sqrt(n);kc2=sqrt(Q);ks=(n+kc1-1)/kc1;
	for(int i=1;i<=n;i++) bl[i]=(i-1)/kc1+1;ks=bl[n];
	for(int i=1;i<=ks;i++) L[i]=(i-1)*kc1+1,R[i]=min(i*kc1,n);
	for(int i=1;i<=Q;i++) Read(q[i].op),Read(q[i].l),Read(q[i].r),Read(q[i].k),q[i].bh=i,Op[i]=q[i].op;
	sort(q+1,q+1+Q);
	for(int l=1,r;r<=Q;l=r+1)
	{
		r=l;
		while(q[r+1].k==q[l].k) r++;
		if(r-l+1>=kc2) sol1(l,r);
		else sol2(l,r);
	}
	sol();
	for(int i=1;i<=Q;i++)
		if(Op[i]==2) printf("%d\n",ans[i]);
	
	}
	return 0;
}
2022/3/9 12:43
加载中...