zoukankan      html  css  js  c++  java
  • 【AtCoder】ARC099题解

    C - Minimization

    每次操作必然包含一个1
    枚举第一次操作的位置计算两边即可

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define MAXN 100005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int N,K;
    int a[MAXN],pos[MAXN];
    int C(int x) {
        return x % (K - 1) == 0 ? x / (K - 1) : x / (K - 1) + 1;
    }
    void Solve() {
        read(N);read(K);
        for(int i = 1 ; i <= N ; ++i) {read(a[i]);pos[a[i]] = i;}
        int ans = N;
        for(int i = 1 ; i <= N ; ++i) {
    	if(i + K - 1 >= pos[1]) {
    	    ans = min(ans,C(i - 1) + C(N - min((i + K - 1),N)) + 1);
    	}
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    D - Snuke Numbers

    我们对于N 只要能求出(f(N + 1))((f(x))表示大于等于(x)的数中(frac{x}{S(x)})最小的那个)
    那么就能不断找到下一个数了

    怎么求呢,我们可以认为一个可以被取到的数一定是x的一段前缀,加上中间某个数修改,后面的所有数都改成9

    因为999999...9999是一个合法的数,那么可以认为(f(x))的位数和(x)一定相同

    如果我们找到一个数(a),它的第d位与x不同,且它后面不都是9,那么我们可以把第d位-1,后面全部修改成9

    所以我们找的数的数目有限,都找出来找最小的(frac{x}{S(x)})即可

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define MAXN 100005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int K,t[25],tot,cnt,s[10005];
    int64 L[10005],p[25],b[25];
    int S(int64 x) {
        int res = 0;
        while(x) {res += x % 10;x /= 10;}
        return res;
    }
    
    int64 f(int64 x) {
        tot = 0;cnt = 0;int64 h = x;
        while(h) {t[++tot] = h % 10;h /= 10;}
        int64 num = 0;
        for(int i = tot ; i >= 1 ; --i) {
    	for(int j = t[i] ; j <= 9 ; ++j) {
    	    int64 tmp = num + j * b[i - 1] + p[i - 1];
    	    if(tmp >= x) L[++cnt] = tmp;
    	}
    	num = num + t[i] * b[i - 1];
        }
        
        for(int i = 1 ; i <= cnt ; ++i) s[i] = S(L[i]);
        int r = 1;
        for(int i = 2 ; i <= cnt ; ++i) {
    	int64 h = L[i] * s[r] - L[r] * s[i];
    	if(h < 0) r = i;
    	else if(h == 0 && L[i] < L[r]) r = i; 
        }
        return L[r];
    }
    void Solve() {
        read(K);
        int64 N = 1;
        p[1] = 9;
        for(int i = 2 ; i <= 16 ; ++i) p[i] = p[i - 1] * 10 + 9;
        b[0] = 1;
        for(int i = 1 ; i <= 16 ; ++i) b[i] = b[i - 1] * 10;
        while(K--) {
    	out(N);enter;
    	N = f(N + 1);
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    E - Independence

    反图必然是个二分图,不然则无解

    我们希望知道哪些分的情况可以达到,就直接把一个二分图的联通块拿出来,做分组背包即可

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define MAXN 100005
    #define mp make_pair
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int N,M;
    int g[705][705];
    struct node {
        int to,next;
    }E[1000005];
    int sumE,head[705],tot,col[705],que[705],qr;
    pii conn[705];
    bool f[2][705];
    void add(int u,int v) {
        E[++sumE].next = head[u];
        E[sumE].to = v;
        head[u] = sumE;
    }
    bool dfs(int u) {
        if(col[u] == -1) col[u] = 0;
        que[++qr] = u;
        for(int i = head[u] ; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(col[v] == col[u]) return false;
    	else if(col[v] == -1) {
    	    col[v] = col[u] ^ 1;
    	    if(!dfs(v)) return false;
    	}
        }
        return true;
    }
    void Solve() {
        read(N);read(M);
        int u,v;
        for(int i = 1 ; i <= M ; ++i) {
    	read(u);read(v);
    	g[u][v] = g[v][u] = 1;
        }
        for(int i = 1 ; i <= N ; ++i) {
    	for(int j = i + 1 ; j <= N ; ++j) {
    	    if(!g[i][j]) {add(i,j);add(j,i);}
    	}
        }
        memset(col,-1,sizeof(col));
        for(int i = 1 ; i <= N ; ++i) {
    	if(col[i] == -1) {
    	    qr = 0;
    	    if(!dfs(i)) {puts("-1");return;}
    	    int cnt[2] = {0,0};
    	    for(int j = 1 ; j <= qr ; ++j) cnt[col[que[j]]]++;
    	    conn[++tot] = mp(cnt[0],cnt[1]);
    	}
        }
        int cur = 0;
        f[0][0] = 1;
        for(int i = 1 ; i <= tot ; ++i) {
    	memset(f[cur ^ 1],0,sizeof(f[cur ^ 1]));
    	for(int j = N ; j >= 0 ; --j) {
    	    if(j >= conn[i].fi) f[cur ^ 1][j] |= f[cur][j - conn[i].fi];
    	    if(j >= conn[i].se) f[cur ^ 1][j] |= f[cur][j - conn[i].se];
    	}
    	cur ^= 1;
        }
        int ans = N * N;
        for(int i = 0 ; i <= N ; ++i) {
    	if(f[cur][i]) {
    	    ans = min(i * (i - 1) / 2 + (N - i) * (N - i - 1) / 2,ans);
    	}
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    F - Eating Symbols Hard

    一道神奇的题

    我们把操作S构成的A数组用一个多项式表示出来
    (t(S) = sum_{i = -10^9}^{10^9} A_{i}X^{i})
    如果往S前面添加一个字符的话
    (t<(S) = t(S)X^{-1})
    (t>(S) = t(S)X)
    (t+(S) = t(S) + 1)
    (t-(S) = t(S) - 1)
    那么我们对于最终的序列求一个哈希值c,如果一段区间操作后的结果和c一样的话就有
    (t_{S_i}t_{S_{i + 1}}...t_{S_j}(0) = c)
    由于这些操作可逆,可以一层一层拆开
    可以得到
    (t_{S_N}^{-1}...t_{S_i}^{-1}t_{S_i}t_{S_{i + 1}}...t_{S_j}(0) = t_{S_N}^{-1}...t_{S_i}^{-1}(c))
    那么我们可以得到
    (t_{S_N}^{-1}...t_{S_{j + 1}}^{-1} (0) = t_{S_N}^{-1}...t_{S_{i}}^{-1}(c))
    这个后缀积可以线性处理出来,维护未知数前的系数即可

    然后就是愉快的用map查询了

    那么,冲突怎么考虑?题解说是冲突的概率在2N/模数大小,让用6个,然而我写的不优美,T掉了,改成5个卡着时限A了,感觉用不上太多也是对的啊

    代码

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cmath>
    #include <map>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define eps 1e-7
    #define MAXN 250005
    #define MOD 999999137
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    typedef vector<int> poly;
     
    template<class T>
    void read(T &res) {
    	res = 0;char c = getchar();T f = 1;
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		res = res * 10 + c - '0';
    		c = getchar();
    	}
    	res *= f;
    }
    template<class T>
    void out(T x) {
    	if(x < 0) {putchar('-');x = -x;}
    	if(x >= 10) {
    		out(x / 10);
    	}
    	putchar('0' + x % 10);
    }
    int B[] = {0,823,727,401,271,571};
    int InvB[10];
    int f[8][MAXN],g[8][MAXN],N,h[8][MAXN];
    char s[MAXN];
    map<int,int> MK[8];
     
     
    int mul(int a,int b) {
    	return 1LL * a * b % MOD;
    }
    int inc(int a,int b) {
    	return a + b >= MOD ? a + b - MOD : a + b;
    }
    void update(int &x,char c,int id) {
    	if(c == '<') x = mul(x,InvB[id]);
    	else if(c == '>') x = mul(x,B[id]);
    	else if(c == '+') x = inc(x,1);
    	else x = inc(x,MOD - 1);
    }
    int fpow(int x,int c) {
    	int res = 1,t = x;
    	while(c) {
    		if(c & 1) res = mul(res,t);
    		t = mul(t,t);
    		c >>= 1;
    	}
    	return res;
    }
    void Solve() {
    	for(int i = 1 ; i <= 5 ; ++i) InvB[i] = fpow(B[i],MOD - 2);
    	read(N);
    	scanf("%s",s + 1);
    	int c[10] = {0};
    	for(int k = 1 ; k <= 5 ; ++k) {
    		for(int i = N ; i >= 1 ; --i) {
    			update(c[k],s[i],k);
    		}
    	}
    	for(int k = 1 ; k <= 5 ; ++k) h[k][N + 1] = 1,g[k][N + 1] = c[k],MK[k][0] += 1;
    	int64 ans = 0;
    	for(int i = N ; i >= 1 ; --i) {
    		int add = N - i + 1;
    		for(int k = 1 ; k <= 5 ; ++k) {
    			if(s[i] == '<') {
    				g[k][i] = inc(g[k][i + 1],MOD - mul(h[k][i + 1],c[k]));
    				h[k][i] = mul(h[k][i + 1],B[k]);
    				g[k][i] = inc(g[k][i],mul(h[k][i],c[k]));
    				f[k][i] = f[k][i + 1];		
    			}
    			else if(s[i] == '>') {
    				g[k][i] = inc(g[k][i + 1],MOD - mul(h[k][i + 1],c[k]));
    				h[k][i] = mul(h[k][i + 1],InvB[k]);
    				g[k][i] = inc(g[k][i],mul(h[k][i],c[k]));
    				f[k][i] = f[k][i + 1];
    			}
    			else if(s[i] == '+') {
    				h[k][i] = h[k][i + 1];
    				g[k][i] = inc(g[k][i + 1],MOD - h[k][i]);
    				f[k][i] = inc(f[k][i + 1],MOD - h[k][i]);
    			}
    			else {
    				h[k][i] = h[k][i + 1];
    				g[k][i] = inc(g[k][i + 1],h[k][i]);
    				f[k][i] = inc(f[k][i + 1],h[k][i]);
    			}
    			add = min(add,MK[k][g[k][i]]);
    			MK[k][f[k][i]] += 1;
    		}
    		ans += add;
    	}
    	out(ans);enter;	
    }
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	Solve();
    	return 0;
    }
    
  • 相关阅读:
    python:封装连接数据库方法
    Python:self理解
    python:pytest优秀博客
    python:pytest中的setup和teardown
    python:单元测试框架pytest的一个简单例子
    java中的static关键字解析
    浅谈Java中的final关键字
    SpringMVC+Spring+Mybatis框架集成
    Mybatis学习总结(四)——输入映射和输出映射
    Mybatis学习总结(三)——SqlMapConfig.xml全局配置文件解析
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9812586.html
Copyright © 2011-2022 走看看