O(nlog2n) 做法,但是不知道为什么只有 10分
求各位大佬帮帮孩子吧
/*
考虑一个盒子 x 完全被没气球后
连接了的区间为 [l,r]
考虑寻找 r>=R>=L>=l 且 x in [L,R] 的区间
考虑将 R 从小到大排序,然后将 L 按第二关键字从小到大排序
用主席树去存,不会出现重复的情况,因为以前计算的情况绝对没有 x,后面计算的请况会出现一个现在没出现的 y
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+50;
int n,m,a[N];
struct jgt
{
int l,r;
}son[N];
bool cmp(jgt t1,jgt t2)
{
if(t1.r!=t2.r) return t1.r<t2.r;
return t1.l<t2.l;
}
int rt[N],tot;
struct jgt1
{
int l,r,sum;
}tr[N*20];
void add(int &wz,int last,int l,int r,int md,int x)
{
wz=++tot;
tr[wz]=tr[last];
tr[wz].sum++;
if(l==r) return ;
int mid=(l+r)/2;
if(md<=mid) add(tr[wz].l,tr[last].l,l,mid,md,x);
else add(tr[wz].r,tr[last].r,mid+1,r,md,x);
}
int update(int wz,int last,int l,int r,int le,int ri)
{
if(!wz) return 0;
if(le<=l&&ri>=r) return tr[wz].sum-tr[last].sum;
int mid=(l+r)/2;
if(le<=mid&&ri>mid) return update(tr[wz].l,tr[last].l,l,mid,le,ri)+update(tr[wz].r,tr[last].r,mid+1,r,le,ri);
if(le<=mid) return update(tr[wz].l,tr[last].l,l,mid,le,ri);
return update(tr[wz].r,tr[last].r,mid+1,r,le,ri);
}
bool t[N*4];
void BT(int wz,int l,int r)
{
t[wz]=true;
if(l==r) return ;
int mid=(l+r)/2;
BT(wz*2,l,mid);
BT(wz*2+1,mid+1,r);
}
void del(int wz,int l,int r,int md)
{
if(l==r) {t[wz]=false;return ;}
int mid=(l+r)/2;
if(md<=mid) del(wz*2,l,mid,md);
else del(wz*2+1,mid+1,r,md);
t[wz]=(t[wz*2]|t[wz*2+1]);
}
bool qur(int wz,int l,int r,int le,int ri)
{
if(le<=l&&ri>=r) return t[wz];
int mid=(l+r)/2;
if(le<=mid&&ri>mid) return (qur(wz*2,l,mid,le,ri)|qur(wz*2+1,mid+1,r,le,ri));
if(le<=mid) return qur(wz*2,l,mid,le,ri);
return qur(wz*2+1,mid+1,r,le,ri);
}
int Q,sr,ans=0;
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
BT(1,1,n);
for(int i=1;i<=m;i++)
scanf("%d %d",&son[i].l,&son[i].r);
sort(son+1,son+m+1,cmp);
for(int i=1;i<=m;i++)
add(rt[i],rt[i-1],1,n,son[i].l,1);
scanf("%d",&Q);
while(Q--)
{
scanf("%d",&sr);
sr=(sr+ans-1)%n+1;
a[sr]--;
if(!a[sr])
{
del(1,1,n,sr);
int l=1,r=sr,mid,zuo,you,ir,il;
while(l<r)
{
mid=(l+r)/2;
if(qur(1,1,n,mid,sr)) l=mid+1;
else r=mid;
}
zuo=l;
l=sr,r=n;
while(l<r)
{
mid=(l+r+1)/2;
if(qur(1,1,n,sr,r)) r=mid-1;
else l=mid;
}
you=r;
l=1,r=m;
while(l<r)
{
mid=(l+r+1)/2;
if(son[mid].r>you) r=mid-1;
else l=mid;
}
ir=r;
l=1,r=m;
while(l<r)
{
mid=(l+r)/2;
if(son[mid].r<sr) l=mid+1;
else r=mid;
}
il=l;
if(sr<=son[il].r&&son[il].r<=you) ans+=update(rt[ir],rt[il-1],1,n,zuo,sr);
}
printf("%d\n",ans);
}
return 0;
}