1. 程式人生 > >牛客多校7

牛客多校7

ase ace rst gcc 技術分享 prot 好的 bre size

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

牛客多校7