cf450 BCDE(待补)

editorial:http://codeforces.com/blog/entry/56294

B题:

#include<bits/stdc++.h>

using namespace std;
#define LL long long
#define N 100010
#define MOD 1000000007
int main(){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    for(int i=1;i<=b;++i){
        a*=10;
        int p=a/b;
        if(p==c){
            printf("%d\n",i);exit(0);
        }
        a%=b;
    }
    puts("-1");
}

C题:

题意:给一个N个数的排列,要求移走一个数,使得record数最多。record数就是这个数比排在它前面的数都大
题目:http://codeforces.com/contest/900/problem/C
参考:https://www.cnblogs.com/Roni-i/p/8026518.html
http://blog.csdn.net/a664607530/article/details/78807933
http://blog.csdn.net/littlewhite520/article/details/78779992
解题思路:如果a[i]如果是a[1..i]中最大的数字那么record会减少1。对于任意一个a[j],且i

#include <set>  
#include <stack>  
#include <queue>  
#include <vector>  
#include <bitset>  
#include <functional>  
#include <ctime>  

using namespace std;  

#define LL long long  
const int INF = 0x3f3f3f3f;  

int n, a[100009], cnt[100009];  

int main()  
{  
    while (~scanf("%d", &n))  
    {  
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);  
        memset(cnt, 0, sizeof cnt);  
        int mx1 = 0, mx2 = 0;  
        for (int i = 1; i <= n; i++)  
        {  
            if (a[i] > mx1)  
            {  
                mx2 = mx1;  
                mx1 = a[i];  
                cnt[a[i]]--;  
            }  
            else if (a[i] > mx2)  
            {  
                cnt[mx1]++;  
                mx2 = a[i];  
            }  
        }  
        int ans, mx = -10;  
        for (int i = 1; i <= n; i++)  
            if (cnt[i] > mx) mx = cnt[i], ans = i;  
        printf("%d\n", ans);  
    }  
    return 0;  
}  

D题:
容斥+组合数学的隔板法。

#include<bits/stdc++.h>

using namespace std;
#define LL long long
#define N 100010
#define MOD 1000000007



vector<int>vec;
LL q_pow(LL a,LL n){
    LL ret=1;
    LL p=a%MOD;
    while(n){
        if(n&1)ret=(ret*p)%MOD;
        p=(p*p)%MOD;
        n>>=1;
    }
    return ret;
}
int main(){
    //freopen("in.txt","r",stdin);
    int x,y;scanf("%d%d",&x,&y);
    if(y%x!=0){puts("0");return 0;}
    y=y/x;
    int tmp=y;
    for(int i=2;i*i<=y;++i){
        if(tmp%i==0)vec.push_back(i);
        while(tmp%i==0)tmp/=i;
    }if(tmp!=1)vec.push_back(tmp);
    int len=vec.size();
    LL ans=0;
    for(int i=0;i<(1<<len);++i){
        int sign=1;
        LL temp=1;
        int j=0;
        for(j;j<len;++j){
            if((1<<j)&i)temp*=vec[j],sign=-sign;
            if(temp>y)break;
        }
        if(temp>y)continue;
        ans=(ans+q_pow(2,y/temp-1)*sign+MOD)%MOD;
    }
    printf("%lld\n",(ans%MOD+MOD)%MOD);
}

别人莫比乌斯

E:E. Maximum Questions
题目网址:http://codeforces.com/contest/900/problem/E

E. Maximum Questions
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Vasya wrote down two strings s of length n and t of length m consisting of small English letters ‘a’ and ‘b’. What is more, he knows that string t has a form “abab…”, namely there are letters ‘a’ on odd positions and letters ‘b’ on even positions.

Suddenly in the morning, Vasya found that somebody spoiled his string. Some letters of the string s were replaced by character ‘?’.

Let’s call a sequence of positions i, i + 1, …, i + m - 1 as occurrence of string t in s, if 1 ≤ i ≤ n - m + 1 and t1 = si, t2 = si + 1, …, tm = si + m - 1.

The boy defines the beauty of the string s as maximum number of disjoint occurrences of string t in s. Vasya can replace some letters ‘?’ with ‘a’ or ‘b’ (letters on different positions can be replaced with different letter). Vasya wants to make some replacements in such a way that beauty of string s is maximum possible. From all such options, he wants to choose one with the minimum number of replacements. Find the number of replacements he should make.
Input

The first line contains a single integer n (1 ≤ n ≤ 105) — the length of s.

The second line contains the string s of length n. It contains small English letters ‘a’, ‘b’ and characters ‘?’ only.

The third line contains a single integer m (1 ≤ m ≤ 105) — the length of t. The string t contains letters ‘a’ on odd positions and ‘b’ on even positions.
Output

Print the only integer — the minimum number of replacements Vasya has to perform to make the beauty of string s the maximum possible.
Examples
Input

5
bb?a?
1

Output

2

Input

9
ab??ab???
3

Output

2

Note

In the first sample string t has a form ‘a’. The only optimal option is to replace all characters ‘?’ by ‘a’.

In the second sample using two replacements we can make string equal to “aba?aba??”. It is impossible to get more than two occurrences.
900E - Maximum Questions

Let’s find all positions i in string s such that occurrence t can start at position i after making some replacements.

How to find them? As t has a form “abab…” letters si, si + 2, si + 4, …, s(i + m - 1|i + m - 2) should be equal to ‘?’ or ‘a’ and si + 1, si + 3…, s(i + m - 1|i + m - 2) should be equal to ‘?’ or ‘b’. Let’s calculate f[i][с] — how many consecutive letters si, si + 2, …, s(f[i][c] - 1)·2 are equal to ‘?’ or c.

Than it is left to verify for position i or f[i][a] ≥ cell(n / 2) and f[i][b] ≥ floor(n / 2). We found all positions where occurrence of t can start.

Remaining task can be solved using dynamic programming. Let dp[i][j] — the minimum number of replacements should be done that the number of occurrences in prefix i is exactly maximum possible minus j.

How to calculate this dp? If from position i + 1 can be started occurrence than dp[i + m][MaxOccuri + m - (MaxOccuri - j)] = best(dp[i + m][MaxOccuri + m - (MaxOccuri - j)], dp[i][j] + CountQuestionsi + 1, i + m). Where CountQuestionsi, j means the number of letter ‘?’ in substring from position i to j and MaxOccuri means the maximum number of occurrences in prefix from position 1 to i, that can be calculated greedily.

Actually considering j > 1 is redundant. Really, if we consider such set of occurrences that exists prefix for which the number of occurrences at least two less than maximum possible than we always can find the larger set of occurrences taking the maximum possible in this prefix and maybe deleting one that intersects with the prefix.

The answer is dp[n][0].

Time complexity O(n).

别人代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=100005;
char str[MAXN];
struct Data
{
    int a,b;
    Data(int _a=0,int _b=0):a(_a),b(_b){}
    Data operator + (const Data &t)const
    {
        return Data(a+t.a,b+t.b);
    }
    bool operator < (const Data &t)const
    {
        return (a==t.a ? b>t.b : a<t.a);
    }
}dp[MAXN];
int go[MAXN][2],cnt[MAXN];
int main()
{
    int n,m;
    scanf("%d%s%d",&n,str+1,&m);
    for(int i=1;i<=n;i++)
        cnt[i]=cnt[i-1]+(str[i]=='?');
    for(int i=n;i>=1;i--)
    {
        if(str[i]!='b')go[i][0]=go[i+1][1]+1;
        if(str[i]!='a')go[i][1]=go[i+1][0]+1;
    }
    for(int i=1;i<=n;i++)
    {
        dp[i]=dp[i-1];
        if(i>=m && go[i-m+1][0]>=m)
            dp[i]=max(dp[i],dp[i-m]+Data(1,cnt[i]-cnt[i-m]));
    }
    return 0*printf("%d\n",dp[n].b);
}
#include<bits/stdc++.h>
using namespace std;
#define maxn 100100
#define P pair<int,int>
#define fi first
#define se second
char s[maxn];
int pre[maxn],n,m,sum[maxn][2][2];
P cmp(P x,P y)
{
    if(x.fi!=y.fi) return (x.fi>y.fi?x:y);
    return (x.se<y.se?x:y);
}
P dp[maxn];
int main()
{
    scanf("%d",&n);
    scanf("%s",s+1);
    scanf("%d",&m);
    for(int i=1;i<=n;++i)
    {
        pre[i]=pre[i-1];
        for(int j=0;j<2;++j)
            for(int k=0;k<2;++k)
                sum[i][j][k]=sum[i-1][j][k];
        if(s[i]=='?') pre[i]++;
        else if(s[i]=='a') ++sum[i][0][i&1];
        else ++sum[i][1][i&1];
    }
    for(int i=m;i<=n;++i)
    {
        int las=i-m+1;
        bool ok=1;
        int g;
        if(las&1) g=0;
        else g=1;
        int tmp=sum[i][0][g]-sum[las-1][0][g];
        if(tmp>0) ok=0;
        g^=1;
        tmp=sum[i][1][g]-sum[las-1][1][g];
        if(tmp>0) ok=0;
        if(ok)
        {
            int add=pre[i]-pre[las-1];
            dp[i]=P(dp[las-1].fi+1,dp[las-1].se+add);
            dp[i]=cmp(dp[i],dp[i-1]);
        }
        else dp[i]=dp[i-1];
        //printf("i=%d,fi=%d,se=%d\n",i,dp[i].fi,dp[i].se);
    }
    printf("%d\n",dp[n].se);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值