• 2019DX#6


    Solved Pro.ID Title Ratio(Accepted / Submitted)
      1001 Salty Fish 16.28%(7/43)
     OK 1002 Nonsense Time                暴力 7.88%(57/723)
      1003 Milk Candy 12.90%(4/31)
      1004 Speed Dog 26.97%(48/178)
      1005 Snowy Smile 8.52%(225/2640)
      1006 Faraway 27.92%(98/351)
      1007 Support or Not 8.33%(3/36)
      1008 TDL 27.63%(921/3333)
      1009 Three Investigators 7.14%(1/14)
      1010 Ridiculous Netizens            点分治 38.71%(24/62)
      1011 11 Dimensions 13.47%(64/475)
      1012 Stay Real 45.04%(1044/2318)

    1002 Nonsense Time

    题意

    给定一个长度n($n le 50000$)的排列$p_1, p_2, ... ,p_n$,给定一个长度为n的排列$a_1, a_2, ... ,a_n$.

    初始排列p是不可见的,从1到n,第$p_{a_i}$个可见,输出此时可见p的LIS。

    数据保证纯随机。

    思路

    由于是随机,所以有人证明lis的期望是O($sqrt{n}$)。

    所以我们利用时间倒流技术,从后往前做。

    记录一个LIS,如果要删除的数是LIS上的,就重新算一个LIS,如果要删的数不再LIS上,那什么事也没发生。

    复杂度 = $ n imes lgroup frac{1}{sqrt{n}}  imes n  imes log n + frac{1}{sqrt{n}} group$

       = $n  imes sqrt{n}  imes log n + sqrt{n}$

    // #pragma GCC optimize(2)
    // #pragma GCC optimize(3)
    // #pragma GCC optimize(4)
    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    // #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    using namespace std;
    #define pb push_back
    #define fi first
    #define se second
    #define debug(x) cerr<<#x << " := " << x << endl;
    #define bug cerr<<"-----------------------"<<endl;
    #define FOR(a, b, c) for(int a = b; a <= c; ++ a)
    
    typedef long long ll;
    typedef long double ld;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
    
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9+7;
    
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
    
    /**********showtime************/
                const int maxn = 50009;
                int p[maxn],a[maxn];
                int vis[maxn],used[maxn], ans[maxn];
                int que[maxn], dp[maxn];
                int n;
                int solve() {
                    int len = 0;
                    for(int i=1; i<=n; i++) {
                        used[i] = 0;
                        if(vis[i]) continue;
                        int pos = lower_bound(que+1, que+1+len, p[i]) - que;
                        if(pos > len) {
                            que[++len] = p[i];
                            dp[i] = len;
                        }
                        else {
                            que[pos] = p[i];
                            dp[i] = pos;
                        }
    //                    for(int i=1; i<=len; i++) cout<<que[i]<<" ";
    //                    cout<<endl;
                    }
                    int res = len;
                    for(int i=n; i>=1; i--) {
                        if(vis[i]) continue;
                        if(dp[i] == len) {
                            used[i] = 1;
                            len--;
                        }
                    }
                    return res;
                }
    int main(){
                int T;  scanf("%d", &T);
                while(T--) {
                    scanf("%d", &n);
                    for(int i=1; i<=n; i++) scanf("%d", &p[i]);
                    for(int i=1; i<=n; i++) scanf("%d", &a[i]);
                    for(int i=1; i<=n; i++) vis[i] = 0;
    
                    int cur = solve();
    
                    for(int i=n; i>=1; i--) {
                        ans[i] = cur;
                        vis[a[i]] = 1;
                        if(used[a[i]] != 0) {
                            cur = solve();
                        }
                    }
                    for(int i=1; i<n; i++) printf("%d ", ans[i]);
                    printf("%d
    ", ans[n]);
                }
                return 0;
    }
    View Code

    1011 11 Dimensions

    我自己用DP1A了,好像还有康托展开的方法,可以搞搞

    // #pragma GCC optimize(2)
    // #pragma GCC optimize(3)
    // #pragma GCC optimize(4)
    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    // #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    using namespace std;
    #define pb push_back
    #define fi first
    #define se second
    #define debug(x) cerr<<#x << " := " << x << endl;
    #define bug cerr<<"-----------------------"<<endl;
    #define FOR(a, b, c) for(int a = b; a <= c; ++ a)
    
    typedef long long ll;
    typedef long double ld;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
    
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9+7;
    
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
    
    /**********showtime************/
                const int maxn = 5e4+9;
                ll big = 1e18;
                ll dp[maxn][22];
                ll md[maxn],mdd[maxn];
                char str[maxn];
                vector<int>vec;
    int main(){
                md[0] = 1;
                for(int i=1; i<maxn; i++) md[i] = md[i-1] * 10 % mod;
                int T;      scanf("%d", &T);
                while(T--) {
                    int n,m,q;
                    scanf("%d%d%d", &n, &m, &q);
                    mdd[0] = 1;
    
                    for(int i=1; i<maxn; i++) mdd[i] = mdd[i-1] * 10 % m;
    
                    scanf("%s", str+1);
                    ll sum = 0, tp = 0;
                    vec.clear();
                    for(int i=0; i<=n; i++) {
                        for(int j=0; j<m; j++) dp[i][j] = 0;
                    }
    
                    for(int i=n; i>=1; i--) {
                        if(str[i] == '?') {
                            if(vec.size() < 25) vec.pb(i);
                        }
                        else {
                            sum = (sum + md[n-i] * (str[i] - '0') % mod) % mod;
                            tp = (tp + mdd[n-i] * (str[i] - '0') % m) % m;
                        }
                    }
                    dp[0][tp] = 1;
    
                    int all = vec.size();
                    for(int i=1; i<=all; i++) {
                        int id = vec[i-1];
                        for(int j=0; j<10; j++) {
                            int up = mdd[n - id] * j % m;
    
                            for(int k=0; k<m; k++) {
                                ll tmp = dp[i][k] + dp[i - 1][(k - up + m) % m];
                                if(tmp <= big) {
                                    dp[i][k] = tmp;
                                }
                                else dp[i][k] = big+1;
                            }
                        }
                    }
    
                    while(q--) {
                        ll cur = sum;
                        int flag = 1;
                        int y = 0;
                        ll k;
    
                        scanf("%lld", &k);
                        k--;
                        for(int i=all; i>=1; i--) {
                            int id = vec[i-1];
                            int flag = 1;
                            for(int j=0; j<10; j++) {
                                int tmp = (y + j * mdd[n-id] % m) % m;
                                if(dp[i-1][(m - tmp) % m] > k) {
                                    y = tmp;
                                    cur = (cur + j * md[n-id] % mod) % mod;
                                    flag = 0;
                                    break;
                                }
                                else {
                                    k -= dp[i-1][(m - tmp) % m];
                                }
                            }
                            if(flag) {k=1; break;}
                        }
                        if(k) puts("-1");
                        else
                            printf("%lld
    ", cur);
                    }
                }
                return 0;
    }
    View Code

      

  • 相关阅读:
    winform笔记
    深度GHOST安装,GHOST完毕后不能启动继续
    CSS+JS;JS+CSS换肤总结
    windows2008配置来
    ul li做标题列表中间出现多的一个空行,重复。
    洛谷P3376 【模板】网络最大流
    洛谷P3387 【模板】缩点
    洛谷P3796 【模板】AC自动机(加强版)
    洛谷P3384 【模板】树链剖分
    洛谷P3919 【模板】可持久化数组(可持久化线段树/平衡树)
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/11317113.html
Copyright © 2020-2023  润新知