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;
    }
    

      

  • 相关阅读:
    SCILAB简介[z]
    UG OPEN API编程基础 2约定及编程初步
    Office 2003与Office 2010不能共存的解决方案
    UG OPEN API 编程基础 3用户界面接口
    NewtonRaphson method
    UG OPEN API编程基础 13MenuScript应用
    UG OPEN API编程基础 14API、UIStyler及MenuScript联合开发
    UG OPEN API编程基础 4部件文件的相关操作
    UG OPEN API编程基础 1概述
    16 UG Open的MFC应用
  • 原文地址:https://www.cnblogs.com/zj75211/p/8365607.html
Copyright © 2011-2022 走看看