1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<bitset> #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std;
const int maxn=1e5+5;
struct QST{ int l,r,i,k; }; bool cmpQ(const QST &a,const QST &b) {return a.k<b.k || a.k==b.k && a.r<b.r;}
int n,m,sqrtn,a[maxn],l1[maxn],r1[maxn],l2[maxn],r2[maxn],l3[maxn],r3[maxn];
struct B{int val,i;} b[maxn]; bool cmpB(const B &a,const B &b) {return a.val<b.val;} int maxr; void discretize() { fo(i,1,n) b[i]=(B){a[i],i}; sort(b+1,b+1+n,cmpB); int cnt=1; fo(i,1,n) { if (i==1 || b[i].val>b[i-1].val) maxr+=cnt, cnt=1; else cnt++; a[b[i].i]=maxr; } }
int Ans[maxn],q0,tong[maxn]; QST q[2*maxn]; bitset<maxn> bs[maxn/3],nowbs; void add(int x) { nowbs[x+(++tong[x])-1]=1; } void del(int x) { nowbs[x+(tong[x]--)-1]=0; } void solve(int ql,int qr) { int qnum=qr-ql+1; q0=0; fo(i,ql,qr) { q[++q0]=(QST){l1[i],r1[i],i-ql+1,l1[i]/sqrtn}; q[++q0]=(QST){l2[i],r2[i],i-ql+1,l2[i]/sqrtn}; q[++q0]=(QST){l3[i],r3[i],i-ql+1,l3[i]/sqrtn}; } sort(q+1,q+1+q0,cmpQ); fo(i,1,qnum) bs[i].set(); nowbs.reset(); memset(tong,0,sizeof(tong)); memset(Ans,0,sizeof(Ans)); fo(i,1,q0) Ans[q[i].i]+=q[i].r-q[i].l+1; int nowl,nowr; fo(i,1,q0) if (i==1) { fo(j,q[i].l,q[i].r) add(a[j]); bs[q[i].i]&=nowbs; nowl=q[i].l, nowr=q[i].r; } else { for(; q[i].l<nowl; nowl--) add(a[nowl-1]); for(; nowr<q[i].r; nowr++) add(a[nowr+1]); for(; nowl<q[i].l; nowl++) del(a[nowl]); for(; q[i].r<nowr; nowr--) del(a[nowr]); bs[q[i].i]&=nowbs; } fo(i,1,qnum) { Ans[i]-=bs[i].count()*3; printf("%d\n",Ans[i]); } }
int main() { scanf("%d %d",&n,&m); fo(i,1,n) scanf("%d",&a[i]); fo(i,1,m) scanf("%d %d %d %d %d %d",&l1[i],&r1[i],&l2[i],&r2[i],&l3[i],&r3[i]); discretize(); sqrtn=sqrt(n); int m1=m/3, m2=m1<<1; if (1<=m1) solve(1,m1); if (m1<m2) solve(m1+1,m2); if (m2<m) solve(m2+1,m); }
|