The Preliminary Contest for ICPC Asia Shanghai 2019

Posted c4lnn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了The Preliminary Contest for ICPC Asia Shanghai 2019相关的知识,希望对你有一定的参考价值。

Link

Solutions


B. Light bulbs

题意:

思路:
差分数组
区间内操作次数为奇数次则灯为打开状态
代码:


[View Code]

#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
int main()
{
    int T;
    scanf("%d",&T);
    int n,m;
    int l,r;
    for(int i=1;i<=T;i++)
    {
        mp.clear();
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&l,&r);
            mp[l]++,mp[r+1]--;
        }
        int sum=0,res=0,pre;
        for(auto y:mp)
            if(y.second)
            {
                if(sum&1) res+=y.first-pre;
                sum+=y.second;
                pre=y.first;
            }
        printf("Case #%d: %d
",i,res);
    }
    return 0;
}

D. Counting Sequences I

题意:

思路:
dfs
将序列分为 (1)(!1)
已知 ({!1}_{min})(2)
先考虑 (!1) 的个数,取最小值 (2)(2^{12}>3000) 因此至多取 (11)
再考虑 (!1) 最大值,易得:序列中 (1) 越多,(!1_{max}) 越大,且序列中至少有 (2)(!1)
(({!1}_{max}*2)-({!1}_{max}+2)=2998longrightarrow {!1}_{max}=3000)
计算 (ans) 时 有重复元素的排列组合 :如(1112233)(res=frac{7!}{3!*2!*2!})
另外预处理阶乘及其逆元
代码:


[View Code]

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int mod=1e9+7;
ll fac[3001];//阶乘 
ll infac[3001];//逆元 
ll ans[3001];
ll a[3001];//数列 
int v[3001];// i在数组中的个数 
ll qPow(ll n,int a)
{
    ll res=1;
    while(a)
    {
        if(a&1) res=res*n%mod;
        n=n*n%mod;
        a>>=1;
    }
    return res;
}
void calc(int cur,int cnt)
{
    for(int i=1;i<=cur;i++) v[a[i]]++;
    int res=fac[cnt];
    for(int i=1;i<=3000;i++) if(v[i]>1) res=res*infac[v[i]]%mod;
    ans[cnt]=(ans[cnt]+res)%mod;    
} 
void dfs(int cur,int start,int idx,ll mul,ll sum,ll cnt) 
{
    if(cur==0) 
    {
        memset(v,0,sizeof v);
        v[1]=mul-sum;
        calc(cnt,mul-sum+cnt);    
        return;
    }
    for(int i=start;i<=3000;i++)
    {
        if(mul*i-sum-i>3000-cnt) return;
        a[idx]=i;
        dfs(cur-1,i,idx+1,mul*i,sum+i,cnt);
    }
}
int main()
{
    memset(ans,0,sizeof ans);
    fac[0]=infac[0]=1;
    for(ll i=1;i<=3000;i++) fac[i]=fac[i-1]*i%mod,infac[i]=infac[i-1]*qPow(i,mod-2)%mod;
    for(int i=2;i<=11;i++) dfs(i,2,1,1,0,i);
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        printf("%d
",ans[n]);
    } 
    return 0;
}

J. Stone game

题意:

思路:
01背包退背包
(a(ain S')) 为最小值
如果 (Sum(S′)?ale Sum(S?S′)) 成立
那么 (forall tin S′,Sum(S′)?tle Sum(S?S′)) 恒成立
先算 (0 1) 背包方案数
再从小到大排序进行退背包
代码:


[View Code]

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int a[400];
int dp[150001];
int main()
{
    int T;
    scanf("%d",&T);
    int n;
    while(T--)
    {
        scanf("%d",&n);
        int s=0,ans=0; 
        for(int i=0;i<n;i++) scanf("%d",&a[i]),s+=a[i];
        sort(a,a+n);
        memset(dp,0,sizeof dp);
        dp[0]=1;
        for(int i=0;i<n;i++) 
            for(int j=s;j>=a[i];j--)
                dp[j]=(dp[j]+dp[j-a[i]])%mod;
        for(int i=0;i<n;i++) 
        {
            for(int j=a[i];j<=s;j++) dp[j]=(dp[j]-dp[j-a[i]]+mod)%mod;
            for(int j=0;j<=s-a[i];j++)
                if(j+a[i]>=s-(j+a[i])&&j<=s-j-a[i])
                    ans=(ans+dp[j])%mod;
        }
        printf("%d
",ans);
    }
    return 0;
}

L. Digit sum

题意:

思路:
预处理
代码:


[View Code]

#include<bits/stdc++.h>
using namespace std;
 
int dp[11][1000001]={0};
 
int main()
{
    for(int i=2;i<=10;i++)
    {
        for(int j=1;j<=1000000;j++)
        {
            int t=j;
            int res=0;
            res=j%i;
            dp[i][j]=res+dp[i][j/i]+dp[i][j-1];    
        }    
    } 
    int T;
    scanf("%d",&T);
    int n,b;
    for(int i=1;i<=T;i++)
    {
        scanf("%d%d",&n,&b);
        printf("Case #%d: %d
",i,dp[b][n]);
    }
    return 0;
}

以上是关于The Preliminary Contest for ICPC Asia Shanghai 2019的主要内容,如果未能解决你的问题,请参考以下文章