牛客多校7

A

队友写的。

//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define fio ios::sync_with_stdio(false);cin.tie(0)
template<typename T>
inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>
inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
 
using namespace std;
 
const double eps=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=500000+10,maxn=4000000+10,inf=0x3f3f3f3f;
 
int ans[N];
int main()
{
    int n;
    scanf("%d",&n);
    int s=n-1;
    while(s>0)
    {
        int len;
        for(int i=20;i>=0;i--)
        {
            if((s>>i)&1)
            {
                len=i+1;
                break;
            }
        }
        int te=s^((1<<len)-1);
        for(int i=te,j=s;i<=s;j--,i++)
            ans[i]=j;
        s=te-1;
    }
    for(int i=0;i<n;i++)
        printf("%d ",ans[i]);
    puts("");
    return 0;
}
/********************
 
********************/
View Code

J

每个点最多向右延伸51个,向下延伸51个,枚举矩阵的左上角,再枚举向右延伸的边有多长,向下延伸的边是单调的

所以复杂度为n * n * 52

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg

using namespace std;

const int N = 1000 + 7;
const int M = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +7;

int n, m, a[N][N], r[N][N], d[N][N], cnt[55];
char s[N][N];

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
        scanf("%s", s[i] + 1);

    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            if(s[i][j] >= 'a' && s[i][j] <= 'z') {
                a[i][j] = s[i][j] - 'a';
            } else {
                a[i][j] = s[i][j] - 'A' + 26;
            }
        }
    }

    for(int i = 1; i <= n; i++) {
        int pos = 1;
        memset(cnt, 0, sizeof(cnt));
        for(int j = 1; j <= m; j++) {
            while(pos <= m && !cnt[a[i][pos]]) cnt[a[i][pos++]]++;
            r[i][j] = pos - j;
            cnt[a[i][j]]--;
        }
    }

    for(int j = 1; j <= m; j++) {
        int pos = 1;
        memset(cnt ,0, sizeof(cnt));
        for(int i = 1; i <= n; i++) {
            while(pos <= n && !cnt[a[pos][j]]) cnt[a[pos++][j]]++;
            d[i][j] = pos - i;
            cnt[a[i][j]]--;
        }
    }

    LL ans = 0;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            int R = r[i][j], D = d[i][j];
            memset(cnt, 0, sizeof(cnt));
            int mn = inf;
            for(int k = 1; k <= D; k++) {
                cnt[r[i + k - 1][j]]++;
                mn = min(mn, r[i + k - 1][j]);
            }
            ans += D;
            for(int k = 2; k <= R; k++) {
                while(D > d[i][j + k - 1]) {
                    cnt[r[i + D - 1][j]]--;
                    D--;
                }
                while(!cnt[mn]) mn++;
                while(mn < k) {
                    cnt[r[i + D - 1][j]]--;
                    D--;
                    while(!cnt[mn]) mn++;
                }
                ans += D;
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}


/*
*/
View Code

E

我们会发现贪心的构造点的数量不够,所以我们用背包使他获得更好的利用。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg

using namespace std;

const int N = 1e6 + 7;
const int M = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +7;

int comb(int n) {
    return n * (n - 1) * (n - 2) * (n - 3) / 4 / 3 / 2;
}

int comb2(int n) {
    return n * (n - 1) * (n - 2) / 3 / 2;
}


int dp[1000001];
int fa[1000001];
int num[1000001];
int cnt[100];
int cnt2[100];
int k, n, m;
vector<pii>ans;

int main() {
//    freopen("a.txt", "w", stdout);
    for(int i = 4; i <= 75; i++) cnt[i] = comb(i);
    for(int i = 3; i <= 75; i++) cnt2[i] = comb2(i);

    n = 63;
    memset(dp, inf, sizeof(dp));
    dp[cnt[n]] = 0;
    int mx = cnt[n];
    for(int i = cnt[n]; i < 1000000; i++) {
        for(int j = 3; j <= n; j++) {
            if(i + cnt2[j] > 1000000) continue;
            if(dp[i] + 1 < dp[i + cnt2[j]]) {
                dp[i + cnt2[j]] = dp[i] + 1;
                fa[i + cnt2[j]] = i;
                num[i + cnt2[j]] = j;
            }
        }
        if(dp[i] > dp[mx]) mx = i;
    }
//    cout << mx << endl;
    scanf("%d", &k);

    if(k <= cnt[n]) {
        for(int i=70;i>=4;i--)
        {
            if(cnt[i]<=k)
            {
                k-=cnt[i];
                n=i;
                break;
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                ans.push_back(mk(i,j));
        int res=0;
        for(int i=70;i>=3;i--)
        {
            int te=i*(i-1)*(i-2)/3/2;
            while(te<=k&&i<=n)
            {
                res++;
                for(int j=1;j<=i;j++)
                    ans.push_back(mk(res+n,j));
                k-=te;
            }
        }
        n+=res;
    } else {
        for(int i = 1; i <= n; i++)
            for(int j = i + 1; j <= n; j++)
                ans.push_back(mk(i, j));

        int tot = n + 1;
        int all = cnt[n];
        while(k != cnt[n]) {
            for(int i = 1; i <= num[k]; i++) ans.push_back(mk(tot, i));
            all += cnt[num[k]];
            k = fa[k];
            tot++;
        }
        n = tot - 1;
    }

    printf("%d %d\n", n, ans.size());
    for(int i = 0; i < ans.size(); i++) printf("%d %d\n", ans[i].fi, ans[i].se);
    return 0;
}


/*
*/
View Code

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9452889.html
今日推荐