HDU - 5845 Best Division dp + 字典树
发布时间:2020-12-16 09:18:27 所属栏目:百科 来源:网络整理
导读:HDU - 5845 dp[ i ] 表示分完前 i 段, 最多能分几段。 我们能得到一个n2的dp, 然后用字典树优化掉。 我用了一个multiset去维护删除, 但实际上因为dp值有单调性, 所有维护sz就够了。 换成c++卡内从卡过去的。 // #pragma GCC optimize(2) // #pragma GCC
HDU - 5845 dp[ i ] 表示分完前 i 段, 最多能分几段。 我们能得到一个n2的dp, 然后用字典树优化掉。 我用了一个multiset去维护删除, 但实际上因为dp值有单调性, 所有维护sz就够了。 换成c++卡内从卡过去的。 //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) //#include<bits/stdc++.h> #include<cstdio> #include<algorithm> #include<set> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL,LL> #define PLI pair<LL,int> #define PII pair<int,int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(),(x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; const double PI = acos(-1); template<class T,class S> inline void add(T &a,S b) {a += b; if(a >= mod) a -= mod;} template<class T,class S> inline void sub(T &a,S b) {a -= b; if(a < 0) a += mod;} template<class T,class S> inline bool chkmax(T &a,S b) {return a < b ? a = b,true : false;} template<class T,class S> inline bool chkmin(T &a,S b) {return a > b ? a = b,true : false;} //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int LOG = 28; int n,up,len; int a[N]; int dp[N]; void read() { int p,q; scanf("%d%d%d",&a[1],&p,&q); for(int i = 2; i <= n; i++) { a[i] = (1LL * a[i - 1] * p + q) % 268435456; } for(int i = 1; i <= n; i++) { a[i] ^= a[i - 1]; } } int trietot,Rt; struct Trie { int ch[2],mx; } tr[N * LOG]; multiset<int> mulset[N * LOG]; inline int newNode() { trietot++; tr[trietot].ch[0] = 0; tr[trietot].ch[1] = 0; tr[trietot].mx = -1; mulset[trietot].clear(); return trietot; } void ins(int x,int val) { int u = Rt; for(int i = LOG - 1; i >= 0; i--) { chkmax(tr[u].mx,val); int v = tr[u].ch[x >> i & 1]; if(!v) tr[u].ch[x >> i & 1] = newNode(); v = tr[u].ch[x >> i & 1]; u = v; } mulset[u].insert(val); chkmax(tr[u].mx,val); } void del(int u,int x,int val,int d) { if(d == -1) { mulset[u].erase(mulset[u].lower_bound(val)); if(SZ(mulset[u])) tr[u].mx = *mulset[u].rbegin(); else tr[u].mx = -1; return; } del(tr[u].ch[x >> d & 1],x,val,d - 1); tr[u].mx = max(tr[tr[u].ch[0]].mx,tr[tr[u].ch[1]].mx); } int query(int x) { int ans = -1; bool limit = true; bool ban = false; int u = Rt; for(int i = LOG - 1; i >= 0; i--) { if(limit) { int sml = x >> i & 1; int big = sml ^ 1; int smlv = tr[u].ch[sml]; int bigv = tr[u].ch[big]; if(!(up >> i & 1)) { u = smlv; } else { if(tr[smlv].mx >= tr[bigv].mx) { limit = false; u = smlv; } else { chkmax(ans,tr[smlv].mx); u = bigv; } } } else { chkmax(ans,tr[u].mx); ban = true; break; } } if(!ban) chkmax(ans,tr[u].mx); return ans; } void init() { tr[0].mx = -1; trietot = 0; Rt = newNode(); } int main() { int T; scanf("%d",&T); while(T--) { init(); scanf("%d%d%d",&n,&up,&len); read(); ins(0,0); for(int i = 1,j = 0; i <= n; i++) { while(j + len < i) { if(dp[j] != -1) del(Rt,a[j],dp[j],LOG - 1); j++; } dp[i] = query(a[i]); if(dp[i] != -1) { dp[i]++; ins(a[i],dp[i]); } } if(dp[n] != -1) printf("%dn",dp[n]); else puts("0"); } return 0; } /* */ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- 做一个像植物大战僵尸的Flash游戏1
- c# – 如何在Roslyn的某个语法节点上判断变量是否在范围内?
- 在PostgreSQL和Dynamics 365 Web API之间构建Python3 auth代
- c – 结构构造函数调用不明确
- FlashBuilder中 Molehill项目运行时 VerifyError: Error #1
- ruby-on-rails – 在Rails中合并实例变量(将数据从控制器传
- c – 使用多线程优化执行时间(简单示例)
- 用sqlite存储Android手机图片,再从数据库读出图片显示。
- 当具有ref参数时,如何使用动态调用C#中的VB6 COM对象?
- .net – WPF的F#异步事件处理程序类似于C#的异步和等待