Title Address: HDU 4638
First wrote a team, MO team can water. Very simple MO team, not much to say.
The code is as follows:
#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>#include <time.h>using namespace STD;#define LL Long Long#define PI ACOs ( -1.0)#pragma COMMENT (linker, "/stack:1024000000")Const intMod=1e9+7;Const intinf=0x3f3f3f3f;Const Doubleeqs=1e-9;Const intmaxn=100000+Ten;intA[MAXN]; LL HA[MAXN], ANS[MAXN], res;structNode {intL, R, ID, POS;} FEI[MAXN];BOOLCMP (node x, node Y) {returnx.pos<y.pos| | X.POS==Y.POS&&X.R<Y.R;}voidReduceintTMP) {if(ha[tmp-1]&&ha[tmp+1]) res++;Else if(!ha[tmp-1]&&!ha[tmp+1]) res--; ha[tmp]=0;}voidAddintTMP) {if(ha[tmp-1]&&ha[tmp+1]) res--;Else if(!ha[tmp-1]&&!ha[tmp+1]) res++; ha[tmp]=1;}intMain () {intT, N, M, I, J, K, TMP, L, R;scanf("%d", &t); while(t--) {scanf("%d%d", &n,&m); for(i=1; i<=n; i++) {scanf("%d", &a[i]); } k=sqrt(n1.0); for(i=0; i<m; i++) {scanf("%d%d", &FEI[I].L,&FEI[I].R); Fei[i].id=i; fei[i].pos=fei[i].l/k; } sort (fei,fei+m,cmp);memset(Ha,0,sizeof(ha)); L=1; R=0; res=0; for(i=0; i<m; i++) { while(R>FEI[I].R) {Tmp=a[r]; Reduce (TMP); r--; } while(R<FEI[I].R) {r++; TMP=A[R]; Add (TMP); } while(L<FEI[I].L) {Tmp=a[l]; Reduce (TMP); l++; } while(L>FEI[I].L) {l--; TMP=A[L]; Add (TMP); } ans[fei[i].id]=res; } for(i=0; i<m; i++) {printf("%i64d\n", Ans[i]); } }return 0;}
Then look at the report of the topic, found that line tree + offline query can also be too. And it feels like a magical thing to do.
First, save it offline. It is then maintained from left to right, maintaining the relative number of previous values for the current enumeration value. For the current number of I, the value of this number is updated to 1, representing a separate string, and then find A[i]-1 and a[i]+1 before there is no existence, if it exists, then the preceding two numbers can not be used as a separate string, relative to the a[i], may coexist in the a[i] string, So the a[i]-1 and a[i]+1 will be 1. Then in the query with R value I, the Direct Line segment tree sums it up. The code is as follows:
#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>#include <time.h>using namespace STD;#define LL Long Long#define PI ACOs ( -1.0)#pragma COMMENT (linker, "/stack:1024000000")#define Root 1, N, 1#define Lson L, Mid, rt<<1#define Rson mid+1, R, Rt<<1|1Const intMod=1e9+7;Const intinf=0x3f3f3f3f;Const Doubleeqs=1e-9;Const intmaxn=100000+Ten;intA[MAXN], POS[MAXN], sum[maxn<<2], ANS[MAXN];structnode{intL, R, id;} FEI[MAXN];BOOLCMP (node x, node Y) {returnX.R<Y.R;}voidPushup (intRT) {sum[rt]=sum[rt<<1]+sum[rt<<1|1];}voidUpdate (intPintXintLintRintRT) {if(L==R) {sum[rt]+=x;return; }intMid=l+r>>1;if(P<=mid) Update (P,x,lson);ElseUpdate (P,x,rson); Pushup (RT);}intQuery (intllintRrintLintRintRT) {if(LL<=L&&RR>=R) {returnSUM[RT]; }intMid=l+r>>1, ans=0;if(Ll<=mid) Ans+=query (Ll,rr,lson);if(Rr>mid) Ans+=query (Ll,rr,rson);returnAns;}intMain () {intT, N, M, I, J;scanf("%d", &t); while(t--) {scanf("%d%d", &n,&m); for(i=1; i<=n;i++) {scanf("%d", &a[i]); Pos[a[i]]=i; } for(i=0; i<m;i++) {scanf("%d%d", &FEI[I].L,&FEI[I].R); Fei[i].id=i; }memset(Sum,0,sizeof(sum)); Sort (fei,fei+m,cmp); j=0; for(i=1; i<=n;i++) {Update (I,1, root);if(a[i]>1&&pos[a[i]-1]<i) Update (pos[a[i]-1],-1, root);if(a[i]<n&&pos[a[i]+1]<i) Update (pos[a[i]+1],-1, root); while(j<m&&fei[j].r<=i) {ans[fei[j].id]=query (fei[j].l,i,root); j + +; } } for(i=0; i<m;i++) {printf("%d\n", Ans[i]); } }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 4638 Group (Mo Team Algorithm | | Line segment Tree discrete query)