[bzoj 3295] [Cqoi 2011] 동적 역순 트 리 배열 주석 트 리
12576 단어 트 리 배열= = = = 데이터 구조 = =나무의장 수
시퀀스 A 에 대한 역순 대 수 는 만족 i 로 정의 합 니 다.
Input
첫 줄 에 두 개의 정수 n 과 m, 즉 초기 요소 의 개수 와 삭 제 된 요소 의 개 수 를 입력 하 십시오.다음 n 줄 마다 1 에서 n 사이 의 정수, 즉 초기 배열 을 포함 합 니 다.아래 m 줄 의 줄 마다 정수 가 있 고 매번 삭 제 된 요소 입 니 다.
Output
출력 은 m 줄 을 포함 하고 모든 요 소 를 삭제 하기 전에 역순 으로 맞 는 갯 수 입 니 다.
Sample Input
5 4
1
5
3
4
2
5
1
4
2
Sample Output
5
2
2
1
예 를 들 어 해석 하 다.
(1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。
HINT
N<=100000 M<=50000
Source
고전 문제...
한 개 씩 삭제 할 때마다 그것 의 앞 이 그 보다 큰 뒤 가 그 보다 작은 공헌 을 줄인다.
이 는... 의장 트 리 자체 기능 을 잘 실현 합 니 다...............................................
주의해 야 할 것 은 이 문 제 는 아버지 께 서 매번 수정 할 때마다 지속 가능 한 방법 으로 삽입 하신 다 는 것 입 니 다. 즉, 새 노드 를 만 들 면 공간 적 으로 감당 할 수 없습니다. 현재 노드 의 역사 버 전 을 방문 하지 않 기 때문에 공간 을 절약 하기 위해 매번 새로 만 들 지 마 세 요. 의장 트 리 의 공간 수요 가 너무 무 섭 습 니 다.
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int INF = 1000000010;
const int SZ = 100010;
int n,m;
int num[SZ];
namespace first{
int tmp[SZ];
int a[SZ];
LL ans = 0;
void mergesort(int l,int r)
{
if(l == r) return ;
int mid = (l + r) >> 1;
mergesort(l,mid); mergesort(mid + 1,r);
int pl = l,pr = mid + 1,p = l;
while(pl <= mid || pr <= r)
{
if(pr > r || (pl <= mid && a[pl] <= a[pr]))
tmp[p ++] = a[pl ++];
else
tmp[p ++] = a[pr ++],ans += mid - pl + 1;
}
for(int i = l;i <= r;i ++)
a[i] = tmp[i];
}
LL get_ans()
{
for(int i = 1;i <= n;i ++)
a[i] = num[i];
mergesort(1,n);
return ans;
}
}
int pos[SZ];
struct segment{
int l,r;
int cnt;
}tree[10000000];
int Tcnt = 0;
int rt[SZ];
void insert(int l,int r,int last,int &now,int x,int d)
{
if(!now) now = ++ Tcnt;
tree[now] = tree[last];
tree[now].cnt += d;
if(l == r) return ;
int mid = l + r >> 1;
if(x <= mid) insert(l,mid,tree[last].l,tree[now].l,x,d);
else insert(mid + 1,r,tree[last].r,tree[now].r,x,d);
}
void change(int pos,int x,int d)
{
for(int i = pos;i <= n;i += i & -i)
insert(1,n,rt[i],rt[i],x,d);
}
int tl,tr;
int tml[SZ],tmr[SZ];
int query_min(int l,int r,int x)
{
int L = 1,R = n;
int ans = 0;
while(L != R)
{
int mid = (L + R) >> 1;
if(mid + 1 <= x)
{
int suml = 0,sumr = 0;
for(int i = 1;i <= tl;i ++) suml += tree[tree[tml[i]].l].cnt;
for(int i = 1;i <= tr;i ++) sumr += tree[tree[tmr[i]].l].cnt;
ans += sumr - suml;
for(int i = 1;i <= tl;i ++) tml[i] = tree[tml[i]].r;
for(int i = 1;i <= tr;i ++) tmr[i] = tree[tmr[i]].r;
L = mid + 1;
}
else
{
for(int i = 1;i <= tl;i ++) tml[i] = tree[tml[i]].l;
for(int i = 1;i <= tr;i ++) tmr[i] = tree[tmr[i]].l;
R = mid;
}
}
return ans;
}
int query_max(int l,int r,int x)
{
int L = 1,R = n;
int ans = 0;
while(L != R)
{
int mid = (L + R) >> 1;
if(mid >= x)
{
int suml = 0,sumr = 0;
for(int i = 1;i <= tl;i ++) suml += tree[tree[tml[i]].r].cnt;
for(int i = 1;i <= tr;i ++) sumr += tree[tree[tmr[i]].r].cnt;
ans += sumr - suml;
for(int i = 1;i <= tl;i ++) tml[i] = tree[tml[i]].l;
for(int i = 1;i <= tr;i ++) tmr[i] = tree[tmr[i]].l;
R = mid;
}
else
{
for(int i = 1;i <= tl;i ++) tml[i] = tree[tml[i]].r;
for(int i = 1;i <= tr;i ++) tmr[i] = tree[tmr[i]].r;
L = mid + 1;
}
}
return ans;
}
int ask_min(int l,int r,int x)
{
tl = 0; tr = 0;
l --;
for(int i = l;i > 0;i -= i & -i)
tml[++ tl] = rt[i];
for(int i = r;i > 0;i -= i & -i)
tmr[++ tr] = rt[i];
return query_min(l,r,x);
}
int ask_max(int l,int r,int x)
{
tl = 0; tr = 0;
l --;
for(int i = l;i > 0;i -= i & -i)
tml[++ tl] = rt[i];
for(int i = r;i > 0;i -= i & -i)
tmr[++ tr] = rt[i];
return query_max(l,r,x);
}
void scanf(int &n)
{
n = 0;
char a = getchar();
bool flag = 0;
while(a < '0'|| a > '9') { if(a == '-') flag = 1; a = getchar(); }
while('0' <= a && a <= '9') { n = n * 10 + a - '0'; a = getchar(); }
if(flag) n = -n;
}
int main()
{
scanf(n); scanf(m);
for(int i = 1;i <= n;i ++)
{
scanf(num[i]);
pos[num[i]] = i;
change(i,num[i],1);
}
LL ans = first :: get_ans();
for(int i = 1;i <= m;i ++)
{
printf("%lld
",ans);
int x;
scanf(x);
change(pos[x],x,-1);
int tmp1 = ask_min(pos[x] + 1,n,x),tmp2 = ask_max(1,pos[x] - 1,x);
ans -= tmp1 + tmp2;
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
HDU 5044 - tree - 트 리 체인 분할 + 트 리 배열누 드 체인 으로 나 뉘 어 데이터 가 좀 큰 것 같 습 니 다.선분 트 리 로 T 를 유지 하고 읽 기 마 우 스 를 추가 하면 트 리 배열 이 지나 갈 수 있 습 니 다...........................
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.