zoukankan      html  css  js  c++  java
  • POJ3378 Crazy Thairs(树状数组+dp+高精度)

    一道经典的树状数组老题,从题目中我们看出要求五元递增组,而普通树状数组只能求二元,我们我们考虑开五维树状数组来求取

    例如 tr[3][x],就代表以x为结尾的三元递增组

    for(i=1;i<=n;i++){
                int pos=find(a[i]);
                add(1,pos,1);
                for(int j=2;j<=5;j++)
                add(j,pos,sum(j-1,pos-1));
            }

    这是核心代码,对于每个数,先将他插在第一维,然后对剩下几维继续dp叠加,add中代表的第几维,在哪个位置,插入前一维前缀和

    本题数据大,要离散化,另外因为答案过大超过long long ,只要贴一个高精度模板即可。

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N =1e5+10;
    const int base =10000;
    vector<int> num;
    class bigint{
        public:
            int num[7],len;
            bigint():len(0){}
            bigint(int n):len(0){
                for(;n>0;n/=base)
                num[len++]=n%base;
            }
            bigint bigvalue(ll n){
                len=0;
                while(n){
                    num[len++]=n%base;
                    len/=base;
                }
                return *this; 
            }
            bigint operator +(const bigint &b){
                bigint c;
                int i;
                int carry=0;
                for(i=0;i<this->len||i<b.len||carry>0;i++){
                    if(i<this->len)
                    carry+=this->num[i];
                    if(i<b.len) carry+=b.num[i];
                    c.num[i]=carry%base;
                    carry/=base;
                }
                c.len=i;
                return c;
            }
            bigint operator +=(const bigint &b){
                *this=*this+b;
                return *this;
            }
            void print(){
                if(len==0){
                    cout<<0<<endl;
                    return ;
                }
                printf("%d",num[len-1]);
                for(int i=len-2;i>=0;i--)
                for(int j=base/10;j>0;j/=10){
                    printf("%d",num[i]/j%10);
                }
                
            }
    };
    typedef bigint big;
    int a[N];
    bigint tr[6][N];
    int n;
    int lowbit(int x){
        return x&-x;
    }
    big sum(int x,int pos){
        int i;
        big res=0;
        for(i=pos;i;i-=lowbit(i)){
            res=res+tr[x][i];
        }
        return res;
    }
    void add(int pos,int x,big v){
        int i;
        for(i=x;i<=n;i+=lowbit(i)){
            tr[pos][i]=tr[pos][i]+v;
        }
    }
    int find(int x){
        return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
    }
    int main(){
        while(cin>>n){
            int i;
            num.clear();
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
                num.push_back(a[i]);
            }
            sort(num.begin(),num.end());
            num.erase(unique(num.begin(),num.end()),num.end());
              memset(tr,0,sizeof tr);
            for(i=1;i<=n;i++){
                int pos=find(a[i]);
                add(1,pos,1);
                for(int j=2;j<=5;j++)
                add(j,pos,sum(j-1,pos-1));
            }
            sum(5,n).print();
        }
    }
    View Code
  • 相关阅读:
    删除文件目录的两种方式
    求两个整数的最大公约数?
    MemCache在Windows环境下的搭建及启动
    hello cnblogs
    Extjs gridPanel可复制配置(转)
    命令模式、状态模式、责任链模式区别(转)
    UML类图几种关系的总结(转)
    观察者模式(转)
    Java之建造者模式(Builder Pattern)(转)
    Java设计模式之工厂方法模式(转) 实现是抽象工厂?
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12296307.html
Copyright © 2011-2022 走看看