Codeforces Round #422 (Div. 2) A B C D

29 篇文章 0 订阅
25 篇文章 1 订阅

A
I’m bored with life
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Holidays have finished. Thanks to the help of the hacker Leha, Noora managed to enter the university of her dreams which is located in a town Pavlopolis. It’s well known that universities provide students with dormitory for the period of university studies. Consequently Noora had to leave Vičkopolis and move to Pavlopolis. Thus Leha was left completely alone in a quiet town Vičkopolis. He almost even fell into a depression from boredom!

Leha came up with a task for himself to relax a little. He chooses two integers A and B and then calculates the greatest common divisor of integers “A factorial” and “B factorial”. Formally the hacker wants to find out GCD(A!, B!). It’s well known that the factorial of an integer x is a product of all positive integers less than or equal to x. Thus x! = 1·2·3·…·(x - 1)·x. For example 4! = 1·2·3·4 = 24. Recall that GCD(x, y) is the largest positive integer q that divides (without a remainder) both x and y.

Leha has learned how to solve this task very effective. You are able to cope with it not worse, aren’t you?

Input
The first and single line contains two integers A and B (1 ≤ A, B ≤ 109, min(A, B) ≤ 12).

Output
Print a single integer denoting the greatest common divisor of integers A! and B!.

Example
input
4 3
output
6
Note
Consider the sample.

4! = 1·2·3·4 = 24. 3! = 1·2·3 = 6. The greatest common divisor of integers 24 and 6 is exactly 6.
水题
代码

#include<bits/stdc++.h>
using namespace std ;
typedef long long LL ;

const int MAXN = 1e3 ;
const int MAXM = 1e5 ;
const int mod  = 1e9+7 ;

__int64 boi(__int64 n){
    LL ans=1;
    for(int i=1;i<=n;i++)
    ans*=i;
    return ans;
}
int main(){
     __int64 a,b;
     scanf("%I64d %I64d",&a,&b);
     LL c=min(a,b);
     printf("%I64d\n",boi(c));
    return  0;
}

B. Crossword solving
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Erelong Leha was bored by calculating of the greatest common divisor of two factorials. Therefore he decided to solve some crosswords. It’s well known that it is a very interesting occupation though it can be very difficult from time to time. In the course of solving one of the crosswords, Leha had to solve a simple task. You are able to do it too, aren’t you?

Leha has two strings s and t. The hacker wants to change the string s at such way, that it can be found in t as a substring. All the changes should be the following: Leha chooses one position in the string s and replaces the symbol in this position with the question mark “?”. The hacker is sure that the question mark in comparison can play the role of an arbitrary symbol. For example, if he gets string s=”ab?b” as a result, it will appear in t=”aabrbb” as a substring.

Guaranteed that the length of the string s doesn’t exceed the length of the string t. Help the hacker to replace in s as few symbols as possible so that the result of the replacements can be found in t as a substring. The symbol “?” should be considered equal to any other symbol.

Input
The first line contains two integers n and m (1 ≤ n ≤ m ≤ 1000) — the length of the string s and the length of the string t correspondingly.

The second line contains n lowercase English letters — string s.

The third line contains m lowercase English letters — string t.

Output
In the first line print single integer k — the minimal number of symbols that need to be replaced.

In the second line print k distinct integers denoting the positions of symbols in the string s which need to be replaced. Print the positions in any order. If there are several solutions print any of them. The numbering of the positions begins from one.

Examples
input
3 5
abc
xaybz
output
2
2 3
input
4 10
abcd
ebceabazcd
output
1
2
水题 暴力
代码

#include<bits/stdc++.h>
using namespace std ;
typedef long long LL ;
//typedef __int64  LL ;

const int MAXN = 1000+10 ;
const int MAXM = 1e5 ;
const int mod  = 1e9+7 ;
const int inf =0x3f3f3f3f;

char s[MAXN],t[MAXN];
int main(){
    int n,m;scanf("%d%d",&m,&n);
    scanf("%s %s",t+1,s+1);
    int mincnt=inf;  int pos;
    for(int i=1;i<=n&&i+m-1<=n;i++){
        int temp=i;int cnt=0;
        for(int j=1;j<=m;j++,temp++){
            if(s[temp]!=t[j])  cnt++;
        }
        if(cnt<mincnt){
            mincnt=cnt;
            pos=i;
        }
    }
    //printf("pos==%d mincnt= %d\n",pos,mincnt);
    int have=0;
    printf("%d\n",mincnt);
    for(int j=1;j<=m;j++){
        if(s[pos++]!=t[j]) {
            if(have++) putchar(' ');
            printf("%d",j);
        }
    }
    return  0;
}

C
Hacker, pack your bags!
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
It’s well known that the best way to distract from something is to do one’s favourite thing. Job is such a thing for Leha.

So the hacker began to work hard in order to get rid of boredom. It means that Leha began to hack computers all over the world. For such zeal boss gave the hacker a vacation of exactly x days. You know the majority of people prefer to go somewhere for a vacation, so Leha immediately went to the travel agency. There he found out that n vouchers left. i-th voucher is characterized by three integers li, ri, costi — day of departure from Vičkopolis, day of arriving back in Vičkopolis and cost of the voucher correspondingly. The duration of the i-th voucher is a value ri - li + 1.

At the same time Leha wants to split his own vocation into two parts. Besides he wants to spend as little money as possible. Formally Leha wants to choose exactly two vouchers i and j (i ≠ j) so that they don’t intersect, sum of their durations is exactly x and their total cost is as minimal as possible. Two vouchers i and j don’t intersect if only at least one of the following conditions is fulfilled: ri < lj or rj < li.

Help Leha to choose the necessary vouchers!

Input
The first line contains two integers n and x (2 ≤ n, x ≤ 2·105) — the number of vouchers in the travel agency and the duration of Leha’s vacation correspondingly.

Each of the next n lines contains three integers li, ri and costi (1 ≤ li ≤ ri ≤ 2·105, 1 ≤ costi ≤ 109) — description of the voucher.

Output
Print a single integer — a minimal amount of money that Leha will spend, or print  - 1 if it’s impossible to choose two disjoint vouchers with the total duration exactly x.

Examples
input
4 5
1 3 4
1 2 5
5 6 1
1 2 4
output
5
input
3 2
4 6 3
2 4 1
3 5 4
output
-1
Note
In the first sample Leha should choose first and third vouchers. Hereupon the total duration will be equal to (3 - 1 + 1) + (6 - 5 + 1) = 5 and the total cost will be 4 + 1 = 5.

In the second sample the duration of each voucher is 3 therefore it’s impossible to choose two vouchers with the total duration equal to 2.

原文链接
思维题目 处理线段问题。
题意 : 给一些有长度的线段,每个线段有个权值,给定x,问恰好两个不相交线段的长度和为x的所有情况中,权值和最小值 。

思路 一 :(官方题解)
这里写图片描述

代码

#include<bits/stdc++.h>
using namespace std;
#define LL long long 

const int N= 2e5+100;
const int M = 1e7;
const int inf = 2e9+10;  
// 以前常用 0x3f3f3f3f 表示inf  1e9多。 int上限 2147483648 。 
// 这道题 inf 最少要是 2e9 往上。 
struct Node{
    int l,len,cost,type;
    Node(){}
    Node(int a,int b,int c,int d){
        l = a ; len = b ;
        cost = c ; type = d ;
    } 
    bool operator<(Node b){
        if(l==b.l) return type<b.type;
        else return l<b.l;
    } 
}P[N*2];

int cost[N];
int main(){
    int n,x;scanf("%d%d",&n,&x);
    int a,b,c;int tot=0;
    for(int i=1;i<=n;++i){
        scanf("%d%d%d",&a,&b,&c);
        P[tot++]={a,b-a+1,c,-1};
        P[tot++]={b,b-a+1,c,1};
    } 
    sort(P,P+tot);
    LL ans=inf;
    fill(cost, cost+x, inf);
    for(int i=0;i<tot;i++){
        Node p=P[i];
        if(p.type==-1){
            if(p.len>=x) continue;
            ans=min(ans,(LL)cost[x-p.len]+(LL)p.cost); // 注意这里会爆int 
        }else 
            cost[p.len]=min(cost[p.len],p.cost);
    }
    printf("%lld\n",ans==inf?-1:ans);
    return 0;
}

暴力
也是很不错的想法。
我们枚举线段长度1-x,然后另一个线段长度也可以用x-i得到,这个时候只要保证线段不相交就可以啦。

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 3E5 + 100, INF = 0X7FFFFFFF;
int n, x, l, r, c;
vector<pair<int, int>> vp[MAXN];


int main()
{
    scanf("%d%d", &n, &x);
    for(int i=0; i<n; ++i)
    {
        scanf("%d%d%d", &l, &r, &c);
        vp[r-l+1].push_back({l, c});
    }
    for(int i=0; i<=x; ++i) sort(vp[i].begin(), vp[i].end());

    int ans = INF;

    for(int d=1; d<x; ++d)
    {
        int mn = INF;
        auto & u=vp[d], &v = vp[x-d];

        for(int i=0, j=0; i<v.size(); ++i)
        {
            while(j<u.size() && u[j].first+d-1<v[i].first)
            {
                if(mn > u[j].second) mn = u[j].second;
                ++j;
            }
            if(mn != INF)
            {
                int s = mn + v[i].second;
                if(ans > s) ans = s;
            }
        }

    }
    if(ans == INF) cout << -1 << endl;
    else cout << ans << endl;

    return 0;
}

D
My pretty girl Noora
time limit per test1.5 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
In Pavlopolis University where Noora studies it was decided to hold beauty contest “Miss Pavlopolis University”. Let’s describe the process of choosing the most beautiful girl in the university in more detail.

The contest is held in several stages. Suppose that exactly n girls participate in the competition initially. All the participants are divided into equal groups, x participants in each group. Furthermore the number x is chosen arbitrarily, i. e. on every stage number x can be different. Within each group the jury of the contest compares beauty of the girls in the format “each with each”. In this way, if group consists of x girls, then comparisons occur. Then, from each group, the most beautiful participant is selected. Selected girls enter the next stage of the competition. Thus if n girls were divided into groups, x participants in each group, then exactly participants will enter the next stage. The contest continues until there is exactly one girl left who will be “Miss Pavlopolis University”

But for the jury this contest is a very tedious task. They would like to divide the girls into groups in each stage so that the total number of pairwise comparisons of the girls is as few as possible. Let f(n) be the minimal total number of comparisons that should be made to select the most beautiful participant, if we admit n girls to the first stage.

The organizers of the competition are insane. They give Noora three integers t, l and r and ask the poor girl to calculate the value of the following expression: t0·f(l) + t1·f(l + 1) + … + tr - l·f(r). However, since the value of this expression can be quite large the organizers ask her to calculate it modulo 109 + 7. If Noora can calculate the value of this expression the organizers promise her to help during the beauty contest. But the poor girl is not strong in mathematics, so she turned for help to Leha and he turned to you.

Input
The first and single line contains three integers t, l and r (1 ≤ t < 109 + 7, 2 ≤ l ≤ r ≤ 5·106).

Output
In the first line print single integer — the value of the expression modulo 109 + 7.

Example
input
2 2 4
output
19
Note
Consider the sample.

It is necessary to find the value of .

f(2) = 1. From two girls you can form only one group of two people, in which there will be one comparison.

f(3) = 3. From three girls you can form only one group of three people, in which there will be three comparisons.

f(4) = 3. From four girls you can form two groups of two girls each. Then at the first stage there will be two comparisons, one in each of the two groups. In the second stage there will be two girls and there will be one comparison between them. Total 2 + 1 = 3 comparisons. You can also leave all girls in same group in the first stage. Then comparisons will occur. Obviously, it’s better to split girls into groups in the first way.

Then the value of the expression is .
题意 让你求个公式 t^0 * f(l) + t^1* f(l + 1) + … + t^r - l*f(r).
而函数 f(n) 代表 为n个人进行两两比赛得出最后冠军,可以分组比(但是每组的人数必须相等),一直重复下去,直到剩下一个人。

一开始的划分尽可能的小,比如6,先按2人一组再按3人一组,这样会比先按3人一组再按2人一组的比较次数要小。
线性筛记录每个数的最小因数,任意一个数的,如果为素数那么只能划分为一组,dp[i]=i*(i-1)/2;
否则dp[i]=i/最小因数 * dp[最小因数] + dp[i/最小因数]。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 

const int maxn=5e6+10;
const int maxm=20;
const int mod=1e9+7;

ll t,l,r;
ll dp[maxn];
int fac[maxn];bool prime[maxn]={0};
void init(){  // 这里用到的欧拉筛 
    for(int i=2;i<maxn;i++)  fac[i]=i;
    for(int i=2;i<maxn;i++){
        if(prime[i]==0){
            for(int j=2;i*j<maxn;j++){
                fac[i*j]=min(fac[i*j],i);
                prime[i*j]=1;
            }
        }
    }

    for(ll i=2;i<maxn;i++){
        if(prime[i])
            dp[i]=(dp[fac[i]]*(i/fac[i])+dp[i/fac[i]])%mod;
        else
            dp[i]=(i*(i-1)/2)%mod;
    }
}

int main(){
    init();
    scanf("%lld%lld %lld",&t,&l,&r);
        ll ans=0;  ll k=1;
        for(int i=l;i<=r;i++){
            ans=(ans+(k*dp[i])%mod)%mod;
            k=(k*t)%mod;
        }
        printf("%lld\n",ans);
    return 0;
}

代码二

#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long  

const int MAXN = 5e6+10;
const int MAXM = 2e7;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;

bool su[MAXN]={1,1,0};int prm[MAXN],sz=0;
int f[MAXN]={0,0,1,3,3};
void init() {  
    for(int i = 2; i < MAXN; ++i) {
        if(!su[i])  prm[sz++] = i;
        for(int j = 0; j < sz; ++j) {
            int t = i * prm[j];
            if(t >= MAXN) break;
            su[t] = true;
            if(i%prm[j] == 0) break;
        }
    }

    for(LL i=5;i<MAXN;i++){
        if(!su[i])   f[i]=(LL)i*(i-1)/2%mod;
        else  {
            for(int j=0;j<sz&&(LL)prm[j]*prm[j]<=i;j++){
                if(i%prm[j]==0){
                    f[i]=(f[i/prm[j]]+(LL)(i/prm[j])*f[prm[j]]%mod)%mod;
                //  printf("i==%d %d  f[i]=%d\n",i,prm[j],f[i]);
                    break;

                }
            }
        }   
    }
}

int main(){
    init();
    int t,l,r;scanf("%d%d%d",&t,&l,&r);
    LL ans=0,temp=1;
    for(int i=l;i<=r;i++){
        ans=(ans+(LL)temp*f[i]%mod)%mod;
    //  printf(" ans =  %d\n",ans);
        temp=temp*t%mod; 
    }
    printf("%lld\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值