• Codeforces Round #311 (Div. 2)题解


    A. Ilya and Diplomas
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Soon a school Olympiad in Informatics will be held in Berland, n schoolchildren will participate there.

    At a meeting of the jury of the Olympiad it was decided that each of the n participants, depending on the results, will get a diploma of the first, second or third degree. Thus, each student will receive exactly one diploma.

    They also decided that there must be given at least min1 and at most max1 diplomas of the first degree, at least min2 and at most max2diplomas of the second degree, and at least min3 and at most max3 diplomas of the third degree.

    After some discussion it was decided to choose from all the options of distributing diplomas satisfying these limitations the one that maximizes the number of participants who receive diplomas of the first degree. Of all these options they select the one which maximizes the number of the participants who receive diplomas of the second degree. If there are multiple of these options, they select the option that maximizes the number of diplomas of the third degree.

    Choosing the best option of distributing certificates was entrusted to Ilya, one of the best programmers of Berland. However, he found more important things to do, so it is your task now to choose the best option of distributing of diplomas, based on the described limitations.

    It is guaranteed that the described limitations are such that there is a way to choose such an option of distributing diplomas that all nparticipants of the Olympiad will receive a diploma of some degree.

    Input

    The first line of the input contains a single integer n (3 ≤ n ≤ 3·106) — the number of schoolchildren who will participate in the Olympiad.

    The next line of the input contains two integers min1 and max1 (1 ≤ min1 ≤ max1 ≤ 106) — the minimum and maximum limits on the number of diplomas of the first degree that can be distributed.

    The third line of the input contains two integers min2 and max2 (1 ≤ min2 ≤ max2 ≤ 106) — the minimum and maximum limits on the number of diplomas of the second degree that can be distributed.

    The next line of the input contains two integers min3 and max3 (1 ≤ min3 ≤ max3 ≤ 106) — the minimum and maximum limits on the number of diplomas of the third degree that can be distributed.

    It is guaranteed that min1 + min2 + min3 ≤ n ≤ max1 + max2 + max3.

    Output

    In the first line of the output print three numbers, showing how many diplomas of the first, second and third degree will be given to students in the optimal variant of distributing diplomas.

    The optimal variant of distributing diplomas is the one that maximizes the number of students who receive diplomas of the first degree. Of all the suitable options, the best one is the one which maximizes the number of participants who receive diplomas of the second degree. If there are several of these options, the best one is the one that maximizes the number of diplomas of the third degree.

    Sample test(s)
    input
    6
    1 5
    2 6
    3 7
    
    output
    1 2 3 
    
    input
    10
    1 2
    1 3
    1 5
    
    output
    2 3 5 
    
    input
    6
    1 3
    2 2
    2 2
    
    output
    2 2 2 
    


    水题:代码例如以下

    #include <bits/stdc++.h>
    #define foreach(it,v) for(__typeof(v.begin()) it = v.begin(); it != v.end(); ++it)
    
    using namespace std;
    const int maxn = 2e5;
    int a[maxn];
    int main(int argc, char const *argv[])
    {
    	ios_base::sync_with_stdio(false);
    	int n,w[3][2];
    	while(cin>>n) {
    		for(int i = 0; i < 3; i++) cin>>w[i][0]>>w[i][1];
    		int a[3];
    		int limt = w[1][0] + w[2][0];
    		a[0] = min(w[0][1],n - limt);
    		n -= a[0];
    		limt = w[2][0];
    		a[1] = min(w[1][1],n - limt);
    		n -= a[1];
    		a[2] = min(n,w[2][1]);
    		printf("%d %d %d
    ", a[0],a[1],a[2]);
    	}
    	return 0;
    }

    B. Pasha and Tea
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Pasha decided to invite his friends to a tea party. For that occasion, he has a large teapot with the capacity of w milliliters and 2n tea cups, each cup is for one of Pasha's friends. The i-th cup can hold at most ai milliliters of water.

    It turned out that among Pasha's friends there are exactly n boys and exactly n girls and all of them are going to come to the tea party. To please everyone, Pasha decided to pour the water for the tea as follows:

    • Pasha can boil the teapot exactly once by pouring there at most w milliliters of water;
    • Pasha pours the same amount of water to each girl;
    • Pasha pours the same amount of water to each boy;
    • if each girl gets x milliliters of water, then each boy gets 2x milliliters of water.

    In the other words, each boy should get two times more water than each girl does.

    Pasha is very kind and polite, so he wants to maximize the total amount of the water that he pours to his friends. Your task is to help him and determine the optimum distribution of cups between Pasha's friends.

    Input

    The first line of the input contains two integers, n and w (1 ≤ n ≤ 1051 ≤ w ≤ 109) — the number of Pasha's friends that are boys (equal to the number of Pasha's friends that are girls) and the capacity of Pasha's teapot in milliliters.

    The second line of the input contains the sequence of integers ai (1 ≤ ai ≤ 1091 ≤ i ≤ 2n) — the capacities of Pasha's tea cups in milliliters.

    Output

    Print a single real number — the maximum total amount of water in milliliters that Pasha can pour to his friends without violating the given conditions. Your answer will be considered correct if its absolute or relative error doesn't exceed 10 - 6.

    Sample test(s)
    input
    2 4
    1 1 1 1
    
    output
    3
    input
    3 18
    4 4 4 2 2 2
    
    output
    18
    input
    1 5
    2 3
    
    output
    4.5
    Note

    Pasha also has candies that he is going to give to girls but that is another task...


    排序

    #include <bits/stdc++.h>
    #define foreach(it,v) for(__typeof(v.begin()) it = v.begin(); it != v.end(); ++it)
    
    using namespace std;
    const int maxn = 2e5;
    int a[maxn];
    int main(int argc, char const *argv[])
    {
    	ios_base::sync_with_stdio(false);
    	int n,w;
    	while(cin>>n>>w) {
    		for(int i = 1; i <= n+n; i++) {
    			cin>>a[i];
    		}
    		sort(a+1,a+1+n+n);
    		double M = a[n + 1] / 2.0;
    		M = min(M,a[1]*1.0);
    		double ans = M * n + 2*M*n;
    		if(ans > w) ans = w;
    		printf("%.10f
    ", ans); 
    	}
    	return 0;
    }

    C. Arthur and Table
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Arthur has bought a beautiful big table into his new flat. When he came home, Arthur noticed that the new table is unstable.

    In total the table Arthur bought has n legs, the length of the i-th leg is li.

    Arthur decided to make the table stable and remove some legs. For each of them Arthur determined number di — the amount of energy that he spends to remove the i-th leg.

    A table with k legs is assumed to be stable if there are more than half legs of the maximum length. For example, to make a table with 5legs stable, you need to make sure it has at least three (out of these five) legs of the maximum length. Also, a table with one leg is always stable and a table with two legs is stable if and only if they have the same lengths.

    Your task is to help Arthur and count the minimum number of energy units Arthur should spend on making the table stable.

    Input

    The first line of the input contains integer n (1 ≤ n ≤ 105) — the initial number of legs in the table Arthur bought.

    The second line of the input contains a sequence of n integers li (1 ≤ li ≤ 105), where li is equal to the length of the i-th leg of the table.

    The third line of the input contains a sequence of n integers di (1 ≤ di ≤ 200), where di is the number of energy units that Arthur spends on removing the i-th leg off the table.

    Output

    Print a single integer — the minimum number of energy units that Arthur needs to spend in order to make the table stable.

    Sample test(s)
    input
    2
    1 5
    3 2
    
    output
    2
    
    input
    3
    2 4 4
    1 1 1
    
    output
    0
    
    input
    6
    2 2 1 1 3 3
    4 3 5 5 2 1
    
    output
    8
    

    枚举最高的那个脚的高度H。大于H的直接删掉(后缀和记录代价即可),设高度为H的有x根,小于H的有y根。那么我们必须删掉k = max(y-(x-1),0)根,本题d值较小开个cnt数组记录下即可,假设比較大的话能够用平衡树维护前k小的代价和。

    #include <bits/stdc++.h>
    #define foreach(it,v) for(__typeof(v.begin()) it = v.begin(); it != v.end(); ++it)
    
    using namespace std;
    const int maxn = 2e5;
    int l[maxn],d[maxn];
    vector<int> g[maxn];
    int s[maxn];
    int main(int argc, char const *argv[])
    {
    	ios_base::sync_with_stdio(false);
    	int n;
    	while(cin>>n) {
    		for(int i = 0; i <= 100001; i++) {
    			s[i] = 0;
    			g[i].clear();
    		}
    		for(int i = 1; i <= n; i++) cin>>l[i];
    		for(int i = 1; i <= n; i++) {
    			int x;cin>>x;
    			g[l[i]].push_back(x);
    			s[l[i]] +=x;
    		}
    		vector<int> t;
    		for(int i = 100000; i >= 0; i--) s[i] += s[i+1];
    		for(int i = 0; i <= 100000; i++)if(g[i].size()){
    			t.push_back(i);
    		}
    		int cost = 1e8,sum = 0;
    		int cnt[205];
    		memset(cnt,0,sizeof cnt);
    		foreach(id,t) {
    			int & x = *id;
    			int w = s[x+1] - s[100001];
    			int sz = g[x].size();
    			int d = sz - 1;
    			d = max(sum-d,0);
    			int i;
    			for(i = 0; i <= 200; i++) {
    				d -= cnt[i];
    				w += i*cnt[i];
    				if(d <= 0) break;
    			}
    			w += d*i;
    			cost = min(cost,w);
    			sum += g[x].size();
    			foreach(it,g[x]) {
    				++cnt[*it];
    			}
    		} 
    		printf("%d
    ", cost);
    	}
    	return 0;
    }

    D. Vitaly and Cycle
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    After Vitaly was expelled from the university, he became interested in the graph theory.

    Vitaly especially liked the cycles of an odd length in which each vertex occurs at most once.

    Vitaly was wondering how to solve the following problem. You are given an undirected graph consisting of n vertices and m edges, not necessarily connected, without parallel edges and loops. You need to find t — the minimum number of edges that must be added to the given graph in order to form a simple cycle of an odd length, consisting of more than one vertex. Moreover, he must find w — the number of ways to add t edges in order to form a cycle of an odd length (consisting of more than one vertex). It is prohibited to add loops or parallel edges.

    Two ways to add edges to the graph are considered equal if they have the same sets of added edges.

    Since Vitaly does not study at the university, he asked you to help him with this task.

    Input

    The first line of the input contains two integers n and m ( — the number of vertices in the graph and the number of edges in the graph.

    Next m lines contain the descriptions of the edges of the graph, one edge per line. Each edge is given by a pair of integers aibi(1 ≤ ai, bi ≤ n) — the vertices that are connected by the i-th edge. All numbers in the lines are separated by a single space.

    It is guaranteed that the given graph doesn't contain any loops and parallel edges. The graph isn't necessarily connected.

    Output

    Print in the first line of the output two space-separated integers t and w — the minimum number of edges that should be added to the graph to form a simple cycle of an odd length consisting of more than one vertex where each vertex occurs at most once, and the number of ways to do this.

    Sample test(s)
    input
    4 4
    1 2
    1 3
    4 2
    4 3
    
    output
    1 2
    
    input
    3 3
    1 2
    2 3
    3 1
    
    output
    0 1
    
    input
    3 0
    
    output
    3 1
    
    Note

    The simple cycle is a cycle that doesn't contain any vertex twice.


    加入最少的边构成奇环。并输出方案数。

    首先假设有0条边那么任选3个点就能构成奇环。答案是3 c(n,3)

    假设每一个节点最多仅仅有一条边与其关联且m > 0,那么对于每条边(u,v),任选节点k。仅仅须要加入两条边就能构成奇环。答案是2,m*(n-2)。

    假设存在节点的度大于2,那么推断是否是否是二分图。假设不是意味着已经存在奇环,答案是 0,1

    否则对每一个联通分量仅仅须要在同色节点里任选两个加边就能形成奇环,答案是1,,sum(c(ci[0],2)+c(ci[1],2));

    盗用Quailty的代码QAQ......

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    typedef long long ll;
    vector<int>e[100005];
    int vis[100005],cnt[2];
    bool bfs(int st)
    {
        queue<int>q;
        vis[st]=1;
        q.push(st);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            cnt[vis[u]-1]++;
            for(int i=0;i<e[u].size();i++)
            {
                if(!vis[e[u][i]])
                {
                    vis[e[u][i]]=3-vis[u];
                    q.push(e[u][i]);
                }
                else
                {
                    if(vis[e[u][i]]==vis[u])return 0;
                }
            }
        }
        return 1;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        int a,b;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            e[a].push_back(b);
            e[b].push_back(a);
        }
        int maxd=0;
        for(int i=1;i<=n;i++)
        {
            maxd=max(maxd,(int)e[i].size());
        }
        if(maxd==0)
        {
            printf("3 %I64d
    ",1LL*n*(n-1)*(n-2)/6);
        }
        else if(maxd==1)
        {
            printf("2 %I64d
    ",1LL*m*(n-2));
        }
        else
        {
            bool odd=0;
            ll ans=0;
            for(int i=1;i<=n;i++)
            {
                if(!vis[i])
                {
                    cnt[0]=cnt[1]=0;
                    if(!bfs(i))
                    {
                        odd=1;
                        break;
                    }
                    ans+=1LL*cnt[0]*(cnt[0]-1)/2;
                    ans+=1LL*cnt[1]*(cnt[1]-1)/2;
                }
            }
            if(odd)printf("0 1
    ");
            else printf("1 %I64d
    ",ans);
        }
        return 0;
    }

    E. Ann and Half-Palindrome
    time limit per test
    1.5 seconds
    memory limit per test
    512 megabytes
    input
    standard input
    output
    standard output

    Tomorrow Ann takes the hardest exam of programming where she should get an excellent mark.

    On the last theoretical class the teacher introduced the notion of a half-palindrome.

    String t is a half-palindrome, if for all the odd positions i () the following condition is held: ti = t|t| - i + 1, where |t| is the length of string t if positions are indexed from 1. For example, strings "abaa", "a", "bb", "abbbaa" are half-palindromes and strings "ab", "bba" and "aaabaa" are not.

    Ann knows that on the exam she will get string s, consisting only of letters a and b, and number k. To get an excellent mark she has to find the k-th in the lexicographical order string among all substrings of s that are half-palyndromes. Note that each substring in this order is considered as many times as many times it occurs in s.

    The teachers guarantees that the given number k doesn't exceed the number of substrings of the given string that are half-palindromes.

    Can you cope with this problem?

    Input

    The first line of the input contains string s (1 ≤ |s| ≤ 5000), consisting only of characters 'a' and 'b', where |s| is the length of string s.

    The second line contains a positive integer k —  the lexicographical number of the requested string among all the half-palindrome substrings of the given string s. The strings are numbered starting from one.

    It is guaranteed that number k doesn't exceed the number of substrings of the given string that are half-palindromes.

    Output

    Print a substring of the given string that is the k-th in the lexicographical order of all substrings of the given string that are half-palindromes.

    Sample test(s)
    input
    abbabaab
    7
    
    output
    abaa
    
    input
    aaaaa
    10
    
    output
    aaa
    
    input
    bbaabb
    13
    
    output
    bbaabb
    
    Note

    By definition, string a = a1a2... an is lexicographically less than string b = b1b2... bm, if either a is a prefix of b and doesn't coincide with b, or there exists such i, that a1 = b1, a2 = b2, ... ai - 1 = bi - 1, ai < bi.

    In the first sample half-palindrome substrings are the following strings — aaaaaaabaabaaabbaabbabaabbbbbaab,babbbbbabbbabaab (the list is given in the lexicographical order).



    半回文串指的是对于每一个奇数位置i(1=<i<=(L+1)/2),满足s[i] = s[L-i+1],下标从1開始,给出一个字符串,求字典序第k小的半回文子串。

    Trie的应用,挺奇妙的,把每一个回文子串插到Trie中去。cnt[u]记录u这个子树有多少个串。然后在树上查找即可,

    不能暴力插子串。能够用一个数组ok[i][j]表示子串s[i...j]是否是半回文串,然后对每一个后缀suffix(x)插入。假设ok[x][i]为true就更新cnt数组,插入完之后须要dfs一遍求子树的siz。查找算法例如以下,假设当前到了节点root,子树1和2的大小分别为w1和w2,那么显然以u为结束节点的子串有w = cnt[root]-w1-w2个,假设w>=k那么算法终止。否则更新k = k - w。假设w1 >= k,那么进入子树1,否则更新k = k-w1,进入子树2。

    #include <bits/stdc++.h>
    #define foreach(it,v) for(__typeof(v.begin()) it = v.begin(); it != v.end(); ++it)
    using namespace std;
    const int maxn = 5e3 + 10;
    typedef long long ll;
    char s[maxn];
    bool ok[maxn][maxn];
    int ch[maxn*maxn][2],cnt[maxn*maxn];
    struct Trie
    {
    	int tot;
    	Trie() {
    		cnt[tot = 0] = 0;
    		ch[0][0] = ch[0][1] = -1;
    	}
    	void Insert(const char *s,int st) {
    		int u = 0;
    		for(int i = st; s[i]; i++) {
    			int c = s[i] - 'a';
    			if(ch[u][c]==-1) {
    				ch[u][c] = ++tot;
    				cnt[tot] = 0;
    				ch[tot][0] = ch[tot][1] = -1;
    			}
    			u = ch[u][c];
    			if(ok[st][i])++cnt[u];
    		}
    	}
    	int Init(int u) {
    		if(u==-1) return 0;
    		cnt[u] += Init(ch[u][0]);
    		cnt[u] += Init(ch[u][1]);
    		return cnt[u];
    	}
    };
    int pre(char * s)
    {
    	s[0] = ' ';
    	int n = strlen(s);
    	--n;
    	for(int w = 1; w <= n; w++) {
    		for(int x = 1; x + w -1 <= n; x++) {
    			ok[x][x+w-1] = (s[x]==s[x+w-1]);
    			if(w >= 5) ok[x][x+w-1] &= ok[x+2][x+w-3]; 
    		}
    	}
    	return n;
    }
    void solve(int root,int k)
    {
    	if(k < 1||root==-1) return;
    	int v1 = ch[root][0],v2 = ch[root][1];
    	int w1= (v1 == -1 ? 0 : cnt[v1]),w2 = (v2 == -1? 0: cnt[v2]);
    	int w = cnt[root] - w1 - w2;
    	if(w >= k) return;
    	k -= w;
    	if(w1 >= k) {
    		putchar('a');
    		solve(v1,k);
    	}else {
    		k -= w1;
    		putchar('b');
    		solve(v2,k);
    	}
    }
    int main()
    {	
    	// ios_base::sync_with_stdio(false);
    	// cin.tie(0);
    	int k;
    	while(scanf("%s%d",s+1,&k)==2) {
    		int n = pre(s);
    		Trie A;
    		for(int i = 1; i <= n; i++) A.Insert(s,i);
    		A.Init(0);
    		solve(0,k);
    		putchar('
    ');
    	}
        return 0;
    }


  • 相关阅读:
    Exp7 网络欺诈防范
    Exp6 信息搜集与漏洞扫描
    Exp4 恶意代码分析
    Exp2 后门原理与实践
    PC平台逆向破解实验报告
    See You Again——我最后的汇编程序
    表格标签
    ansible环境搭建
    OSPF_1
    Linux的文件管理(8-27)
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6911422.html
Copyright © 2020-2023  润新知