The Preliminary Contest for ICPC Asia Shanghai 2019
Posted c4lnn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了The Preliminary Contest for ICPC Asia Shanghai 2019相关的知识,希望对你有一定的参考价值。
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的主要内容,如果未能解决你的问题,请参考以下文章
The Preliminary Contest for ICPC Asia Yinchuan 2019
The Preliminary Contest for ICPC Asia Shenyang 2019
The Preliminary Contest for ICPC Asia Shanghai 2019
The Preliminary Contest for ICPC Asia Shanghai 2019