Codeforces Round #256 (Div. 2)思维训练

B. Suffix Structures

Bizon the Champion isn't just a bison. He also is a favorite of the "Bizons" team.

At a competition the "Bizons" got the following problem: "You are given two distinct words (strings of English letters), s and t. You need to transform word s into word t". The task looked simple to the guys because they know the suffix data structures well. Bizon Senior loves suffix automaton. By applying it once to a string, he can remove from this string any single character. Bizon Middle knows suffix array well. By applying it once to a string, he can swap any two characters of this string. The guys do not know anything about the suffix tree, but it can help them do much more.

Bizon the Champion wonders whether the "Bizons" can solve the problem. Perhaps, the solution do not require both data structures. Find out whether the guys can solve the problem and if they can, how do they do it? Can they solve it either only with use of suffix automaton or only with use of suffix array or they need both structures? Note that any structure may be used an unlimited number of times, the structures may be used in any order.

Input

The first line contains a non-empty word s. The second line contains a non-empty word t. Words s and t are different. Each word consists only of lowercase English letters. Each word contains at most 100 letters.

Output

In the single line print the answer to the problem. Print "need tree" (without the quotes) if word s cannot be transformed into word t even with use of both suffix array and suffix automaton. Print "automaton" (without the quotes) if you need only the suffix automaton to solve the problem. Print "array" (without the quotes) if you need only the suffix array to solve the problem. Print "both" (without the quotes), if you need both data structures to solve the problem.

It's guaranteed that if you can solve the problem only with use of suffix array, then it is impossible to solve it only with use of suffix automaton. This is also true for suffix automaton.

Sample test(s)
Input
automaton
tomat
Output
automaton
Input
array
arary
Output
array
Input
both
hot
Output
both
Input
need
tree
Output
need tree
Note

In the third sample you can act like that: first transform "both" into "oth" by removing the first character using the suffix automaton and then make two swaps of the string using the suffix array and get "hot".


#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;

int main()
{
    char a[110],b[110],cnt1[30],cnt2[30];
    while(scanf("%s%s",a,b)!=EOF)
    {
        memset(cnt1,0,sizeof(cnt1));
        memset(cnt2,0,sizeof(cnt2));
        int len1=strlen(a),len2=strlen(b);
        for(int i=0;i<len1;i++)
        {
            cnt1[a[i]-'a']++;
        }
        for(int i=0;i<len2;i++)
        {
            cnt2[b[i]-'a']++;
        }
        int mark=0,mark1=1;
        int j=0;
        for(int i=0;i<len1;i++)
        {
            if(a[i]==b[j])
            {
                j++;
            }
            if(j==len2)
            {
                mark=1;
            }
        }
        int mark2=1;
        for(int i=0;i<26;i++)
        {
            if(cnt1[i]!=cnt2[i])
            {
                mark2=0;
            }
            if(cnt1[i]<cnt2[i])
            {
                mark1=0;
                mark2=0;
                break;
            }
        }
        if(mark2) printf("array\n");
        else if(mark)
            printf("automaton\n");
        else if(!mark&&mark1)
            printf("both\n");
        else
            printf("need tree\n");

    }
    return 0;
}

C. Painting Fence

Bizon the Champion isn't just attentive, he also is very hardworking.

Bizon the Champion decided to paint his old fence his favorite color, orange. The fence is represented as n vertical planks, put in a row. Adjacent planks have no gap between them. The planks are numbered from the left to the right starting from one, the i-th plank has the width of 1 meter and the height of ai meters.

Bizon the Champion bought a brush in the shop, the brush's width is 1 meter. He can make vertical and horizontal strokes with the brush. During a stroke the brush's full surface must touch the fence at all the time (see the samples for the better understanding). What minimum number of strokes should Bizon the Champion do to fully paint the fence? Note that you are allowed to paint the same area of the fence multiple times.

Input

The first line contains integer n (1 ≤ n ≤ 5000) — the number of fence planks. The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 109).

Output

Print a single integer — the minimum number of strokes needed to paint the whole fence.

Sample test(s)
Input
5
2 2 1 2 1
Output
3
Input
2
2 2
Output
2
Input
1
5
Output
1
Note

In the first sample you need to paint the fence in three strokes with the brush: the first stroke goes on height 1 horizontally along all the planks. The second stroke goes on height 2 horizontally and paints the first and second planks and the third stroke (it can be horizontal and vertical) finishes painting the fourth plank.

In the second sample you can paint the fence with two strokes, either two horizontal or two vertical strokes.

In the third sample there is only one plank that can be painted using a single vertical stroke.

思路:分治的思想,先找到当前组最矮的,然后加上差值,然后递归求解,两边的解,返回的时候要比较一下横着刷和竖着刷那个更好

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=5010;
const int INF=1e9+10;
typedef long long LL;
int a[maxn],n;
int dfs(int l,int r,int cur)
{
    if(l==r)return 0;
    int min1=INF;
    for(int i=l;i<r;i++)min1=min(min1,a[i]);
    int ans=min1-cur;
    int now=l;
    for(int i=l;i<r;i++)
    {
        if(a[i]==min1)
        {
            ans+=dfs(now,i,min1);
            now=i+1;
        }
    }
    ans+=dfs(now,r,min1);
    return min(r-l,ans);
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    cout<<dfs(0,n,0)<<endl;
    return 0;
}

D. Multiplication Table

Bizon the Champion isn't just charming, he also is very smart.

While some of us were learning the multiplication table, Bizon the Champion had fun in his own manner. Bizon the Champion painted an n × m multiplication table, where the element on the intersection of the i-th row and j-th column equals i·j (the rows and columns of the table are numbered starting from 1). Then he was asked: what number in the table is the k-th largest number? Bizon the Champion always answered correctly and immediately. Can you repeat his success?

Consider the given multiplication table. If you write out all n·m numbers from the table in the non-decreasing order, then the k-th number you write out is called the k-th largest number.

Input

The single line contains integers n, m and k (1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m).

Output

Print the k-th largest number in a n × m multiplication table.

Sample test(s)
Input
2 2 2
Output
2
Input
2 3 4
Output
3
Input
1 10 5
Output
5
Note

A 2 × 3 multiplication table looks like this:

1 2 3
2 4 6
题意:给一个矩阵,定义元素的值为i*j,问第k大的数

思路:二分答案,然后利用乘法表的性质判断,第i行小于x数的个数为x/i


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
long long n,m,k;
bool can(LL mid)
{
    LL sum=0;
    for(int i=1;i<=n;i++)
    {
        if(mid<i)break;
        sum+=min(m,mid/i);
    }
    return sum>=k;
}
void solve()
{
    LL l=1,r=n*m,mid;
    while(l<r)
    {
        mid=l+(r-l)/2;
        if(can(mid))r=mid;
        else l=mid+1;
    }
    cout<<l<<endl;
}
int main()
{
    cin>>n>>m>>k;
    if(n>m)swap(n,m);
    solve();
    return 0;
}

E. Divisors

Bizon the Champion isn't just friendly, he also is a rigorous coder.

Let's define function f(a), where a is a sequence of integers. Function f(a) returns the following sequence: first all divisors of a1 go in the increasing order, then all divisors of a2 go in the increasing order, and so on till the last element of sequence a. For example, f([2, 9, 1]) = [1, 2, 1, 3, 9, 1].

Let's determine the sequence Xi, for integer i (i ≥ 0): X0 = [X] ([X] is a sequence consisting of a single number X), Xi = f(Xi - 1) (i > 0). For example, at X = 6 we get X0 = [6], X1 = [1, 2, 3, 6], X2 = [1, 1, 2, 1, 3, 1, 2, 3, 6].

Given the numbers X and k, find the sequence Xk. As the answer can be rather large, find only the first 105 elements of this sequence.

Input

A single line contains two space-separated integers — X (1 ≤ X ≤ 1012) and k (0 ≤ k ≤ 1018).

Output

Print the elements of the sequence Xk in a single line, separated by a space. If the number of elements exceeds 105, then print only the first 105 elements.

Sample test(s)
Input
6 1
Output
1 2 3 6 
Input
4 2
Output
1 1 2 1 2 4 
Input
10 3
Output
1 1 1 2 1 1 5 1 1 2 1 5 1 2 5 10 


思路:先求出n的所有因子,然后递归求解

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=100005;
typedef long long LL;
LL factor[maxn],cnt,n,k,num;
void process()
{
    int m=sqrt(n);
    cnt=num=0;
    for(int i=1;i<=m;i++)
    {
        if(n%i==0)
        {
            factor[cnt++]=i;
            if(n/i!=i)factor[cnt++]=n/i;
        }
    }
    sort(factor,factor+cnt);
}
void dfs(LL x,LL m)
{
    if(num>=100000)return ;
    if(m==0||x==1)
    {
        cout<<x<<" ";
        num++;
        return;
    }
    for(int i=0;i<cnt&&factor[i]<=x;i++)
    {
        if(x%factor[i]==0)
        {
            dfs(factor[i],m-1);
            if(num>=100000)return;
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    cin>>n>>k;
    process();
    dfs(n,k);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值