• 牛客小白月赛13 解题报告


    暂时咕着,慢慢补...赛时几题先放上来

    A

    打个表即可

    #include<bits/stdc++.h>
    using namespace std;
    int main() {
        long long n;
        scanf("%lld",&n);
        if(n & 1) puts("1"); else puts("-1");
    }
    

    B

    枚举端点,hash判断即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    #define N 10100
    #define base 13131
     
    char s[N];
    ull h1[N], p[N], h2[N];
    int n, ans = 0;
     
    ull gh1(int l, int r) { return h1[r] - h1[l - 1] * p[r - l + 1]; }
    ull gh2(int l, int r) { return h2[l] - h2[r + 1] * p[r - l + 1]; }
     
    int main() {
        scanf("%s", s + 1); p[0] = 1;
        n = strlen(s + 1);
        for(int i = 1; i <= n; ++i) s[i + n] = s[i];
        n *= 2;
        for(int i = 1; i <= n; ++i) {
            h1[i] = h1[i - 1] * base + s[i];
            p[i] = p[i - 1] * base;
        }
        for(int i = n; i; i--) h2[i] = h2[i + 1] * base + s[i];
        for(int i = 1; i <= n; ++i) {
            for(int j = i; j - i + 1 <= n / 2 && j <= n; ++j) {
                int mid = (i + j) >> 1;
                if((j - i + 1) & 1 && gh1(i, mid - 1) == gh2(mid + 1, j)) ans = max(ans, j - i + 1);
                if(!((j - i + 1) & 1) && gh1(i, mid) == gh2(mid + 1, j)) ans = max(ans, j - i + 1);
            }
        }
        printf("%d
    ", ans);
    }
    

    C

    考虑答案长什么样子

    [frac{钱数大于3*n的方案数}{总方案数} ]

    这个方案数dp一下就可以了。类似背包。
    然后总方案数是什么呢?考虑每次一共有4种选择,相乘即(4^n)
    用个gcd约分即可。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    ll f[40][130];
    int n;
    
    int main() {
    	cin >> n;
    	f[0][0] = 1;
    	for(int i = 1; i <= n; ++i) {
    		for(int j = 1; j <= 4 * n; ++j) 
    			for(int v = 1; v <= 4; ++v) 
    				if(j - v >= 0) f[i][j] += f[i - 1][j - v];
    	}
    	ll m1 = 0;
    	for(int i = 3 * n; i <= 4 * n; ++i) m1 += f[n][i];
    	ll m2 = pow(4, n), g = __gcd(m1, m2);
    	printf("%lld/%lld
    ", m1 / g, m2 / g);
    }
    

    D

    维护前后缀和,枚举不选点

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 5000010
     
    ll a[N], l[N], r[N];
     
    int main() {
        int n; cin >> n;
        for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]), l[i] = l[i - 1] | a[i];
        for(int i = n; i; --i) r[i] = r[i + 1] | a[i];
        ll ans = 0;
        for(int i = 1; i <= n; ++i) {
            ans = max(ans, l[i - 1] | r[i + 1]);
        }  
        printf("%lld
    ", ans);
    }
    

    E

    倍增floyd,转移的时候相乘即可。注意细节。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define ll long long
    #define inf 0x3f3f3f3f
    #define il inline
    
    namespace io {
    
    #define in(a) a = read()
    #define out(a) write(a)
    #define outn(a) out(a), putchar('
    ')
    
    #define I_int ll
    inline I_int read() {
        I_int x = 0, f = 1;
        char c = getchar();
        while (c < '0' || c > '9') {
            if (c == '-') f = -1;
            c = getchar();
        }
        while (c >= '0' && c <= '9') {
            x = x * 10 + c - '0';
            c = getchar();
        }
        return x * f;
    }
    char F[200];
    inline void write(I_int x) {
        if (x == 0) return (void) (putchar('0'));
        I_int tmp = x > 0 ? x : -x;
        if (x < 0) putchar('-');
        int cnt = 0;
        while (tmp > 0) {
            F[cnt++] = tmp % 10 + '0';
            tmp /= 10;
        }
        while (cnt > 0) putchar(F[--cnt]);
    }
    #undef I_int
    
    }
    using namespace io;
    
    using namespace std;
    
    #define N 110
    const ll mod = 1000000007;
    
    ll K,m,s,n;
    
    struct mat {
        int m[N][N];
        mat operator * (const mat x) const {
            mat c; memset(c.m, 0, sizeof(c.m));
            for(int k = 1; k <= n; ++k) {
                for(int i = 1; i <= n; ++i) {
                    for(int j = 1; j <= n; ++j) {
                        c.m[i][j] += m[i][k] * x.m[k][j] % mod;
                        c.m[i][j] %= mod;
                    }
                }
            }
            return c;
        }
    }d[32];
    
    int main() {
        in(n);in(m);in(K);in(s); int tot = 0;
        for(int i = 1; i <= m; ++i) {
        	int x, y; in(x), in(y);
        	d[0].m[x][y]++;
        }
        for(int i = 1; (1 << i) <= K; ++i) d[i] = d[i - 1] * d[i - 1];
        mat ans;
        --K; ans = d[0];
        for(int i = 0; (1 << i) <= K; ++i) if((K>>i)&1) ans = ans * d[i];
        ll sum = 0;
    	for(int i = 1; i <= n; ++i) {
    		if(i == s) continue;
    		if(ans.m[s][i]!=-1) sum += ans.m[s][i] % mod;
    		sum %= mod;
    	}
    	outn(sum);
    }
    

    H

    单调栈板子。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 1000100
    int a[N], n, k, h[N], w[N], s[N];
    ll ans = 0;
     
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        for(int i = 1; i <= n; ++i) scanf("%d", &h[i]), ans = max(ans, (ll)h[i] * a[i]);
        int top = 0;
        for(int i = 1; i <= n; ++i) {
            if(a[i] > h[s[top]]) {
                s[++top] = i, w[top] = 1;
            } else {
                ll W = 0;
                while(top && h[s[top]] > h[i]) {
                    W += w[top];
                    ans = max(ans, (ll)W * h[s[top]]);
                    --top;
                }
                s[++top] = i; w[top] = W + a[i];
            }
        }
        printf("%lld
    ", ans);
    }
    

    I

    做一下nim,如果必败就枚举要取哪个,如果都不行那就还是必败

    #include <bits/stdc++.h>
    using namespace std;
    #define N 100010
    int a[N], s, n, k;
      
    int main() {
        cin >> n >> k;
        for(int i = 1; i <= n; ++i) {
            cin >> a[i]; s ^= a[i];
        }
        if(s) return puts("YES"), 0;
        for(int i = 1; i <= n; ++i) {
            int now = s ^ a[i];
            if(a[i] >= k && now ^ (a[i] - k)) return puts("YES"), 0;
        }
        puts("NO");
    }
    

    J

    套路莫反。这里放上推导。复杂度(O(sqrt{n}))

    [egin{aligned} &sum sum (i,j)^2\ &=sum^n d^2sum sum[(i,j)=d]\ &=sum^n d^2 sum_{i=1}^{n/d}sum_{j=1}^{m/d}[(i,j)=1]\ &=sum^n d^2 sum_{k=1}^{n/d}mu(k)frac{n}{kd}frac{m}{kd}\ &T = kd\ &=sum_{T=1}^nfrac{n}{T}frac{m}{T}sum_{k|T}mu(k)(frac{T}{k})^2\ &id^2*mu\ &=F(1)=1, F(p)=p^2-1, F(p^2)=F(p)*p^2 end{aligned} ]

    [egin{aligned} &sum_{k|T}mu(k)(frac{T}{k})^2\ &mu*id^2\ &F(1)=1\ &F(p)=1*(p/1)^2+(-1)*(p/p)^2=p^2-1\ &F(p^2)=1*(p^2/1)^2+(-1)*p^2+0=(p^2)^2-p^2=(p^2-1)*p^2 end{aligned} ]

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 1000100
    #define M 1000000
    const ll mod = 1000000007;
     
    ll n, m;
    int p[N], cnt, vis[N];
    ll F[N];
     
    void init() {
        F[1] = 1;
        for(int i = 2; i <= M; ++i) {
            if(!vis[i]) p[++cnt] = i, F[i] = ((ll)i * i - 1ll) % mod;
            for(int j = 1; i * p[j] <= M && j <= cnt; ++j) {
                vis[i * p[j]] = 1;
                if(i % p[j] == 0) {
                    F[i * p[j]] = F[i] * (p[j] * p[j] % mod) % mod;
                    break;
                }
                F[i * p[j]] = (ll)F[i] * F[p[j]] % mod;
            }
        }
        for(int i = 1; i <= M; ++i) F[i] += F[i - 1], F[i] %= mod;
    }
     
    int main() {
        init();
        scanf("%lld%lld", &n, &m);
        if(n > m) swap(n, m);
        ll ans = 0;
        for(ll l = 1, r; l <= n; l = r + 1) {
            r = min(n / (n / l), m / (m / l));
            ans = (ans + (ll)(n / l) * (m / l) % mod * ((F[r] - F[l - 1] + mod) % mod) % mod) % mod;
        }
        printf("%lld
    ", (ans % mod + mod) % mod);
    }
    
  • 相关阅读:
    cvsmooth平滑处理函数
    对图像频率的一些理解
    VIM 如何切换buffer
    Mplab X IDE 安装DMCI
    测试 使用橘子曰
    wlr设置 Blog Ping
    wlr快捷键
    使用Windows Live Writer写文章时不要用360清除垃圾
    如何将Windows live writer草稿转存到其他电脑上
    使用windows live writer写cnblog-1 安装wlr
  • 原文地址:https://www.cnblogs.com/henry-1202/p/10699252.html
Copyright © 2020-2023  润新知