1. 程式人生 > >●POJ 3378 Crazy Thairs

●POJ 3378 Crazy Thairs

元組 ++ query brush air 查詢 ongl lap reset

題鏈:

http://poj.org/problem?id=3378

題解:

樹狀數組維護,高精度。

依次考慮以每個位置結尾可以造成的貢獻。

假設當前位置為i,為了達到5個元素的要求,我們需要求出,在序列1~i-1中有多少個合法4元組$(a<b<c<d且A_a<A_b<A_c<A_d)$的最後那個元素是小於$A_i$的$(即為了滿足a<b<c<d<i且A_a<A_b<A_c<A_d<A_i)$,求出這種四元組的個數,那麽就是以i位置結尾可以貢獻的答案。

所以我們用樹狀數組"D4"維護以權值x結尾的合法四元組的個數,那麽對於當前的A_i,就只需要查詢樹狀數組的[1~A_i-1]的區間的和,這個和便是應該貢獻的答案。

然而為了維護以某一元素結尾的合法四元組的個數,我們不得不再用一個樹狀數組"D3"維護以權值x結尾的合法三元組的個數。

同理,為了維護以某一元素結尾的合法三元組的個數,還需要一個樹狀數組"D2"維護以權值x結尾的合法二元組的個數,然後是一個樹狀數組"D1"維護以權值x結尾的合法一元組的個數。。。。。。

然後就只需要對於依次枚舉到的第i個元素,進行查詢和更新樹狀數組就好了。

(本體比較惡心,爆longlong,就再弄一個高精度咯。)

代碼:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 50050
#define ll long long
using namespace std;
struct BigInt{
	#define Bit 1000
	int val[10],len;
	BigInt(){len=1;memset(val,0,sizeof(val));}
	void operator = (int rtm){
		memset(val,0,sizeof(val));
		len=0; do{
			val[++len]=rtm%Bit; rtm/=Bit;
		}while(rtm);
	}
	BigInt operator + (const BigInt &rtm) const{
		BigInt now; now.len=max(rtm.len,len);
		for(int i=1;i<=now.len;i++){
			now.val[i]+=val[i]+rtm.val[i];
			now.val[i+1]+=now.val[i]/Bit;
			now.val[i]%=Bit;
		}
		while(now.val[now.len+1]) now.len++;
		return now;
	}
	void Print(){
		printf("%d",val[len]);
		for(int i=len-1;i;i--) printf("%03d",val[i]);
	}
};
struct BIT{
	BigInt val[MAXN]; int n;
	int Lowbit(int x){return x&-x;}
	void Reset(int _n){n=_n; while(_n) val[_n]=0,_n--;}
	void Modify(int p,BigInt v){
		while(p<=n) val[p]=val[p]+v,p+=Lowbit(p);
	}
	BigInt Query(int p){
		static BigInt ret; ret=0;
		while(p) 
			ret=ret+val[p],p-=Lowbit(p);
		return ret;
	}
}D1,D2,D3,D4;
int A[MAXN],tmp[MAXN];
int N,tnt;
BigInt ANS,t,one;
int main(){
	one=1;
	while(~scanf("%d",&N)){
		for(int i=1;i<=N;i++) 
			scanf("%d",&A[i]),tmp[i]=A[i];
		sort(tmp+1,tmp+N+1);
		tnt=unique(tmp+1,tmp+N+1)-tmp-1;
		for(int i=1;i<=N;i++)
			A[i]=lower_bound(tmp+1,tmp+tnt+1,A[i])-tmp;
		D1.Reset(tnt); D2.Reset(tnt);
		D3.Reset(tnt); D4.Reset(tnt); ANS=0;
		for(int i=1;i<=N;i++){
			D1.Modify(A[i],one); t=D1.Query(A[i]-1);
			D2.Modify(A[i],t); t=D2.Query(A[i]-1);
			D3.Modify(A[i],t); t=D3.Query(A[i]-1);
			D4.Modify(A[i],t); 
			t=D4.Query(A[i]-1);
			ANS=ANS+t;
		}
		ANS.Print(); printf("\n");
	}	
	return 0;
}

  

●POJ 3378 Crazy Thairs