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 \times \lgroup \frac{1}{\sqrt{n}} \times n \times \log n + \frac{1}{\sqrt{n}} \rgroup$

   = $n \times \sqrt{n} \times \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\n", 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\n", cur);
                }
            }
            return 0;
}
View Code

  

 

posted @ 2019-08-07 18:49  ckxkexing  阅读(171)  评论(0编辑  收藏  举报