HDU5845 Best Division

递归写法,好久不写很容易就gg了...

dp[i]=max(dp[j])+1,并且s[i]XORs[j]<=x 

01字典树优化一下转移。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4
 5 const int maxn = 1e5+5;
 6 ll a[maxn], s[maxn], f[maxn];
 7 int X, L;
 8 struct T{
 9     int node[maxn][2];
10     int val[maxn];
11     ll dp[maxn];
12     int tot;
13     void init(){
14         node[1][0] = node[1][1] = val[1] = 0;
15         dp[1] = -1e9;
16         tot = 2;
17     }
18     int newnode(){
19         node[tot][0] = node[tot][1] = val[tot] = 0;
20         dp[tot] = -1e9;
21         return tot++;
22     }
23     ll query(int x, int now = 1, int dep = 30){
24         if(dep == -1)
25             return dp[now];
26         ll ret = -1e9;
27         int tmp = (X>>dep)&1, tt = (x>>dep)&1;
28         if(tmp){
29             if(node[now][tt]) ret = max(ret, dp[ node[now][tt] ]);
30             if( node[now][!((x>>dep)&1)] ) ret = max(ret,  query(x, node[now][!((x>>dep)&1)], dep-1));
31             return ret;
32         }
33         if(node[now][tt])
34             return query(x, node[now][tt], dep-1);
35         return ret;
36     }
37     void add(int x, int d, ll v, int now = 1, int dep = 30){
38         if(dep == -1){
39             val[now] += d;
40             if(d > 0)
41                 dp[now] = max(dp[now], v);
42             else if(dp[now] <= v)
43                 dp[now] = -1e9;
44             return ;
45         }
46         int tmp = (x>>dep)&1;
47         if(node[now][tmp] == 0)
48             node[now][tmp] = newnode();
49         add(x, d, v, node[now][tmp], dep-1);
50         val[now] += d;
51         dp[now] = -1e9;
52         if(node[now][0]&&val[ node[now][0] ]) dp[now] = max(dp[now], dp[ node[now][0] ]);
53         if(node[now][1]&&val[ node[now][1] ]) dp[now] = max(dp[now], dp[ node[now][1] ]);
54     }
55 };
56 T Tree;
57 int main(){
58     ios::sync_with_stdio(false);
59     int T; cin >> T;
60     ll n, p, q;
61     while(T--){
62         cin >> n >> X >> L;
63         cin >> a[1] >> p >> q;
64         s[1] = a[1];
65         for(int i = 2; i <= n; i++)
66             a[i] = (a[i-1]*p+q)%268435456, s[i] = a[i]^s[i-1];
67
68         Tree.init();
69         Tree.add(s[0], 1, f[0]);
70         int i = 1;
71         for( ; i <= n&&i <= L; i++){
72             f[i] = Tree.query(s[i])+1;
73             Tree.add(s[i], 1, f[i]);
74         }
75         for( ; i <= n; i++){
76             Tree.add(s[i-L-1], -1, f[i-L-1]);
77             f[i] = Tree.query(s[i])+1;
78             Tree.add(s[i], 1, f[i]);
79         }
80         cout << max(f[n], 0LL)<< endl;
81     }
82     return 0;
83 }

时间: 2024-10-09 05:51:10

HDU5845 Best Division的相关文章

【题解】HDU5845 Best Division (tri树)

[题解]HDU5845 Best Division (tri树) 题意:给定你一个序列(三个参数来根),然后请你划分子段.在每段子段长度小于等于\(L\)且子段的异或和\(\le x\)的情况下最大化分出子段的个数 区间/子段/序列这种东西一大性质就是右端点之后与前面无关. \(dp(i)\)表示上一个右端点是\(i\)且前面分出来的子段都满足条件的最多子段个数. 直接转移\(O(n^2)\)考虑优化这个东西,子段转前缀和是应该记起来的套路,现在问题就是变成查询两个前缀和的异或值是否满足条件.

light oj 1214 - Large Division

1214 - Large Division   PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 32 MB Given two integers, a and b, you should check whether a is divisible by b or not. We know that an integer a is divisible by an integer b if and only if

fzuoj1607Greedy division

题目链接: 点我点我 题目:  Problem 1607 Greedy division Accept: 436    Submit: 1590 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description Oaiei has inherited a large sum of wealth recently; this treasure has n pieces of golden coins. Unfortunate

HDU 3480 Division(斜率优化+二维DP)

Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others) Total Submission(s): 3984    Accepted Submission(s): 1527 Problem Description Little D is really interested in the theorem of sets recently. There’s a pro

uva725 Division

题目描述: abcde / fghij =N a,b···j 为0-9任意一个数,且互相不同 任意给一个n(2<=n<=79),输出满足条件的可能 思路1:10!只有不到400w,直接暴力枚举即可 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; int a[]= {1,0,2,3,4,5,6,7,8

BZOJ 1385: [Baltic2000]Division expression

题目 1385: [Baltic2000]Division expression Time Limit: 5 Sec  Memory Limit: 64 MB Description 除法表达式有如下的形式: X1/X2/X3.../Xk 其中Xi是正整数且Xi<=1000000000(1<=i<=k,K<=10000) 除法表达式应当按照从左到右的顺序求,例如表达式1/2/1/2的值为1/4.但可以在表达式中国入括号来改变计算顺序,例如(1/2)/(1/2)的值为1.现给出一个除

bzoj1385: [Baltic2000]Division expression

欧几里得算法.可以发现规律,a[2]作为分母,其他作为分子,必定是最好的选择.判断是否为整数即可. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) int read(){ int x=0;char c=getchar(); whil

Codeforces-808D Array Division 【multiset】

Description Vasya has an array a consisting of positive integer numbers. Vasya wants to divide this array into two non-empty consecutive parts (the prefix and the suffix) so that the sum of all elements in the first part equals to the sum of elements

UVa 725 Division --- 简单枚举

题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=666 /* UVa 725 Division --- 简单枚举 */ #include <cstdio> #include <cstring> bool used[10]; /* 判断传进来的两个数是否满足条件 */ bool judge(int a, i