zoukankan      html  css  js  c++  java
  • ●POJ 3378 Crazy Thairs

    题链:

    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("
    ");
    	}	
    	return 0;
    }
    

      

  • 相关阅读:
    UVA 1025 A Spy in the Metro DP水题
    ZOJ 3814 Sawtooth Puzzle BFS
    ZOJ 3816 Generalized Palindromic Number
    UVA 10859 Placing Lampposts 树形DP
    UVA 11825 Hackers' Crackdown 状压DP
    POJ 2887 Big String 线段树 离线处理
    POJ 1635 Subway tree systems Hash法判断有根树是否同构
    BZOJ 3110 k大数查询 & 树套树
    sdoi 2009 & 状态压缩
    来自于2016.2.24的flag
  • 原文地址:https://www.cnblogs.com/zj75211/p/8365607.html
Copyright © 2011-2022 走看看