多校联合训练hdu5845---Best Divison

来源:互联网 发布:java 安装包 编辑:程序博客网 时间:2024/06/05 09:45

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">一个典型的DP</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">首先总结一下套路:对于那个所谓的简单问题,必须是2维的,因为需要一维来存取i,另一维来表示当前划分的长度,结果表示花费c。</span>

可以通过二分或者是什么其他的限制答案的方法来消除一维或者是+数据结构简化转移。

然而这个是二分花费导致最后的一维减少。那么就是,i一维,结果保存一维,这样的话就可以简化一维。

。。。。。。其实要划分区间,那么套路就是这样的。那也就是d[i] --- d[j] 和 那个。但是存的是划分的次数。。。。

再加上一个01字典树的应用。。。就可以简化转移。。。为0(32) ;

但是怎么写都错,要加强代码的训练。而且必须是有思想的训练。。。

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX         100005#define   MAXN        2000005#define   maxnode     500010#define   sigma_size  30#define   lson        l,m,rt<<1#define   rson        m+1,r,rt<<1|1#define   lrt         rt<<1#define   rrt         rt<<1|1#define   mid         int m=(r+l)>>1#define   LL          long long#define   ull         unsigned long long#define   mem0(x)     memset(x,0,sizeof(x))#define   mem1(x)     memset(x,-1,sizeof(x))#define   meminf(x)   memset(x,INF,sizeof(x))#define   lowbit(x)   (x&-x)#define   S(n)        scanf("%d",&n)#define   P(n)        printf("%d ",n)#define   PN(n)       printf("%d\n",n)#define   FP(k)       freopen(k , "r" ,stdin)#define   RPTI(s , n) for(int i=s;i<n;i++)#define   RPTJ(s , n) for(int j=s;j<n;j++)#define   RPTK(s , n) for(int k=s;k<n;k++)#define   RPTL(s , n) for(int l=s;l<n;l++)const LL     mod   = 1000000;///const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const int    INFF  = 1e9;const double pi    = 3.141592653589793;const double inf   = 1e18;const double eps   = 1e-10;inline int read_int(){    int ret=0;    char tmp;    while(!isdigit(tmp=getchar()));    do{        ret=(ret<<3)+(ret<<1)+tmp-'0';    }    while(isdigit(tmp=getchar()));    return ret;}/*******************************************/typedef long long ll ;typedef pair <int ,int> pii ;#define mk make_pairconst ll moddd = 268435456 ;struct trie{    int ch[MAX][2],tot;    int val[MAX],dp[MAX],fa[MAX];    void build()    {        memset(ch,0,sizeof(ch));    memset(val,0,sizeof(val));    memset(dp,-1,sizeof(dp));    memset(fa,0,sizeof(fa));        tot = 1;    }    void insert(int s,int Val,int dpval)    {        int u = 0;        for(int i = 30;i >= 0;i--)        {            int v = ((1<<i) & s) ? 1 : 0;            if(!ch[u][v]){fa[tot] = u;ch[u][v] = tot++;}            u = ch[u][v];            val[u] += Val;            dp[u] = max(dp[u],dpval);        }if(!val[u]){dp[u] = -1;while(u){u = fa[u];dp[u] = -1;if(ch[u][0] && val[ch[u][0]]) dp[u] = dp[ch[u][0]];if(ch[u][1] && val[ch[u][1]]) dp[u] = max(dp[u],dp[ch[u][1]]);}}    }    int find(int s , int x)     {int u = 0,ans = -1;bool flag = false;for(int i = 30;i >= 0;i--){int v = ((1<<i) & s) ? 1 : 0;int V = ((1<<i) & x) ? 1 : 0;if(V && ch[u][v] && val[ch[u][v]]) ans = max(ans,dp[ch[u][v]]);u = ch[u][V ^ v];if(!u || !val[u]) break;if(i == 0) flag = true;}if(flag) ans = max(ans,dp[u]);return ans;    }} tree;ll arry[200000] ;ll sum[200000] ;ll dp[200000] ;int main(){    int T ; scanf("%d" , &T) ;     while(T --){        int n , x , l ; scanf("%d%d%d" , &n,&x,&l) ;        int ta ,tb ,tc ; scanf("%d%d%d" , &ta,&tb,&tc) ;        tree.build() ;        arry[1] = ta ;        sum[1] = arry[1] ;        for(int i=2;i<=n;i++){            arry[i] = arry[i-1] * tb + tc ; arry[i] %= moddd ;            sum[i] = sum[i-1] ^ arry[i] ;        }        tree.insert(0 , 1 , 0) ;        dp[0] = 0 ;        sum[0] = 0 ;        for(int i=1;i<=n;i++){            if(i-l-1 >= 0 && dp[i-l-1] >= 0) tree.insert(sum[i-l-1] , -1 , -1) ;            int tmp = tree.find(sum[i] , x) ;            dp[i] = tmp + 1 ;            if(tmp == -1) {                dp[i] = -1 ;continue ;            }            tree.insert(sum[i] , 1 , dp[i]) ;            //cout << i <<" "<<sum[i]<< " " << dp[i] << endl ;        }        if(dp[n] == -1) dp[n] = 0 ;        cout << dp[n] << endl ;    }}


0 0