diverta 2019 Programming Contest

AB

签到(A是a-b problem就不放code了)

#include<bits/stdc++.h>
using namespace std;
int r,g,b,n,ans;
int main()
{
    cin>>r>>g>>b>>n;
    for(int i=0;i*r<=n;i++)
    for(int j=0;i*r+j*g<=n;j++)
    if((n-i*r-j*g)%b==0)ans++;
    cout<<ans<<endl;
}
View Code

C

签到,首先把所有字符串内部的AB加上,然后记录3种字符串的个数:仅头是B,仅尾是A,头是B且尾是A,然后把第3种顺次连接,其余加上取个min

#include<bits/stdc++.h>
using namespace std;
int n,ans,s1,s2,s3;
char s[15];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        int len=strlen(s+1);
        for(int i=1;i<len;i++)if(s[i]=='A'&&s[i+1]=='B')ans++;
        if(s[1]=='B'&&s[len]=='A')s3++;
        else if(s[1]=='B')s1++;
        else if(s[len]=='A')s2++;
    }
    if(s3)
    {
        ans+=s3-1;
        if(s1)s1--,ans++;
        if(s2)s2--,ans++;
    }
    cout<<ans+min(s1,s2)<<endl;
}
View Code

D

知道n=[n/m]*m+n%m这道题就是签到题了,设[n/m]=n%m=x,然后n=x(m+1),O(√n)枚举因数即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,ans;
void judge(ll m,ll x)
{
    if(!m)return;
    if(n/m==x&&n%m==x)ans+=m;
}
int main()
{
    cin>>n;
    for(ll i=1;i*i<=n;i++)
    if(n%i==0)
    {
        judge(i-1,n/i);
        if(i*i<n)judge(n/i-1,i);
    }
    cout<<ans;
}
View Code

E

要使每一段异或起来相等,实际上就等价于每一段每一位为1的个数的奇偶性相同。设a[i]为前i个数的异或和。然后如果a[n]!=0,显然只能分成奇数段,然后a[n]为0的位,每一段该位偶数个,a[n]不为0的位,每一段该位奇数个1,然后取断点的值,发现就是a[n] 0 a[n] 0…a[n],然后建两颗线段树,分奇偶讨论一下即可。a[n]=0,可奇可偶,奇数段的话,每一个断点a[i]都要为0,偶数段则是交替x 0 x 0…x 0,然后考虑断开处x=0的情况,可以统计a[i]=0(1<=i<n)的个数x,答案是2x,若x!=0,把x分类,DP一下,遇到0总方案加上前面f[i]的和即可,比较麻烦,细节见code。

#include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int N=5e5+7,M=1048600,mod=1e9+7;
struct tree{
    int sum[N<<2];
    void build(int l,int r,int rt)
    {
        if(l==r){sum[rt]=(l==0);return;}
        int mid=l+r>>1;
        build(lson),build(rson);
        sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
    }
    void update(int k,int v,int l,int r,int rt)
    {
        if(l==r){sum[rt]=v;return;}
        int mid=l+r>>1;
        if(k<=mid)update(k,v,lson);else update(k,v,rson);
        sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)return sum[rt];
        int ret=0,mid=l+r>>1;
        if(L<=mid)ret=(ret+query(L,R,lson))%mod;
        if(R>mid)ret=(ret+query(L,R,rson))%mod;
        return ret;
    }
}tr[2];
int n,ans,psum,tot,a[N],s[20][N],sum[N],pw[N],f[N];
vector<int>G[M];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=0;i<20;i++)for(int j=1;j<=n;j++)s[i][j]=(s[i][j-1]+((a[j]>>i)&1))%2;
    int flag=0;
    for(int i=0;i<20;i++)if(s[i][n])flag=1;
    if(!flag)
    {
        int n0=1,lst=0;
        for(int i=1;i<=n;i++)a[i]^=a[i-1];
        for(int i=1;i<n;i++)
        if(!a[i])n0=2ll*n0%mod,sum[i]=sum[i-1]+1;else G[a[i]].push_back(i),sum[i]=sum[i-1];
        for(int v=1;v<(1<<20);v++)
        if(G[v].size())
        {
            int sz=G[v].size(),pre=0;
            for(int i=0;i<sz;i++)f[i]=0;
            f[0]=1,ans=(ans+1)%mod;
            for(int i=1;i<sz;i++)
            {
                int s0=sum[G[v][i]-1]-sum[G[v][i-1]];
                pre=(pre+1ll*f[i-1]*s0)%mod;
                ans=(ans+pre+1)%mod;
                f[i]=(f[i-1]+pre+1)%mod;
            }
        }
        ans=(ans+n0)%mod;
        printf("%d\n",ans);
        return 0;
    }
    tr[0].build(0,n,1);
    tr[1].build(0,n,1);
    tr[1].update(0,0,0,n,1);
    for(int i=1;i<=n;i++)
    {
        int s1=0,dif=0,add;
        for(int j=0;j<20;j++)
        {
            if(s[j][i])s1++;
            if(s[j][i]!=s[j][n])dif++;
        }
        if(!s1)add=tr[1].query(0,i-1,0,n,1),tr[0].update(i,add,0,n,1);
        if(!dif)add=tr[0].query(0,i-1,0,n,1),tr[1].update(i,add,0,n,1);
    }
    ans=tr[1].query(n,n,0,n,1);
    printf("%d\n",ans);
}
View Code

F

只有IOI2017 rank1会做,咕了。

result:rank67(?)网卡了等结果出了再更。

猜你喜欢

转载自www.cnblogs.com/hfctf0210/p/10850419.html