zoukankan      html  css  js  c++  java
  • CF1097E Egor and an RPG game

    题目链接

    (f(n)) 表示最小的正整数 (k),使得所有长为 (n) 的排列都可以被划分为至多 (k) 个单调子序列。

    给定长为 (n) 的排列 (p),构造将其划分为至多 (f(n)) 个单调子序列的方案。(T) 组数据。

    (sum nle 10^5)


    结论:

    [f(n)=maxleft{kleft|frac{k(k+1)}{2}le n ight. ight} ]

    证明:设 (c(n)) 是上式右边的值。我们可以构造 (p={1,3,2,6,5,4,cdots}),也即分成 (c(n)) 组下降子段,每组长度比上一组长 (1),只能划分为至少 (c(n)) 个单调子序列。可以得到 (f(n)ge c(n))。然后我们考虑对所有 (p) 构造划分为至多 (c(n)) 个单调子序列的方法。

    求出现在的 LIS,设其长度为 (l),若 (l>c(n)),直接划分为一组,因为 (c(n-c(n)-1)le c(n)-1),所以转化为了更小的情况,可以归纳证明。

    (lle c(n)),根据 Dilworth 定理,可以将其划分为 (l) 个下降子序列,实现方法可以用类似二分求 LIS 的方法,维护一些末尾单调上升的下降子序列,每次将 (p_i) 放进第一个末尾比 (p_i) 大的子序列。然后构造完就做完了,时间复杂度 (O(nsqrt nlog n)),还顺便得到了 (f(n)=c(n))

    #include<bits/stdc++.h>
    #define PB emplace_back
    #define MP make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long LL;
    typedef vector<int> vi;
    typedef pair<int, int> pii;
    const int N = 100003, mod = 998244353;
    template<typename T>
    void read(T &x){
    	int ch = getchar(); x = 0; bool f = false;
    	for(;ch < '0' || ch > '9';ch = getchar()) f |= ch == '-';
    	for(;ch >= '0' && ch <= '9';ch = getchar()) x = x * 10 + ch - '0';
    	if(f) x = -x;
    } template<typename T>
    bool chmax(T &a, const T &b){if(a < b) return a = b, 1; return 0;}
    int t, n, a[N]; bool vis[N]; pii tr[N];
    void upd(int p, pii v){for(;p <= n;p += p & -p) chmax(tr[p], v);}
    pii qry(int p){pii res; for(;p;p -= p & -p) chmax(res, tr[p]); return res;}
    vector<vi> ans, res; int from[N];
    void solve(){ read(n); ans.clear(); memset(vis, 0, n+1);
    	for(int i = 1;i <= n;++ i) read(a[i]);
    	int k = 0; while((k*(k+1)>>1) <= n) ++ k;
    	while(k --){
    		memset(tr, 0, n+1<<3);
    		for(int i = 1;i <= n;++ i) if(!vis[i]){
    			pii tt = qry(a[i]); from[i] = tt.se;
    			upd(a[i], MP(tt.fi+1, i));
    		} pii tt = qry(n);
    		if(tt.fi <= k){ res.clear();
    			for(int i = 1;i <= n;++ i) if(!vis[i]){
    				if(res.empty() || a[i] > res.back().back()) res.push_back({a[i]});
    				else {
    					int l = 0, r = res.size()-1;
    					while(l < r){
    						int mid = l+r>>1;
    						if(a[i] > res[mid].back()) l = mid+1;
    						else r = mid;
    					} res[l].PB(a[i]);
    				}
    			} for(auto &u : res) ans.PB(u); break;
    		} vi lis;
    		for(int i = tt.se;i;i = from[i]){lis.PB(a[i]); vis[i] = true;}
    		reverse(lis.begin(), lis.end()); ans.PB(lis);
    	} printf("%llu
    ", ans.size());
    	for(auto &u : ans){ printf("%llu", u.size());
    		for(int _ : u) printf(" %d", _);
    		putchar('
    ');
    	}
    } int main(){read(t); while(t --) solve();}
    
  • 相关阅读:
    unp.h
    美拍视频下载
    动态加载ajax 腾讯视频评论
    已知二叉树的先序,中序遍历,求后续遍历

    JSP九大内置对象及四个作用域
    转换数据库连接池为hikaricp
    JSP Tomcat8.0运行连接池时发生异常【AbstractMethodError oracle.jdbc.driver.T4CConnection.isValid(I)Z】
    tomcat启动时出现There are no resources that can be added or removed from the server
    java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener问题解决
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/14520011.html
Copyright © 2011-2022 走看看