\(B. Mode\)
利用数位 \(dp\) 求数字众数,那么在相同的位数下,相同的个数即为相同,用 \(map\) 记忆化搜索。
int num[20],len=0;
map<pair<int,vector<int> > ,int>mp;
int dfs(int pos,vector<int> v,bool lead,bool limit){
if(!limit){
sort(v.begin(),v.end());
}
if(pos==0){
if(lead)return 1;
return *max_element(v.begin(),v.end());
}
if(!limit&&!lead&&mp.count(make_pair(pos,v))) return mp[make_pair(pos,v)];
int up=limit?num[pos]:9;
int res=0;
for(int i=0;i<=up;i++){
if(!lead||i){
v[i]++;
}
res+=dfs(pos-1,v,lead&&i==0,limit&&i==up);
if(!lead||i){
v[i]--;
}
}
if(!limit&&!lead)mp[make_pair(pos,v)]=res;
return res;
}
int num_dp(int x){
len=0;
while(x){
num[++len]=x%10;
x/=10;
}
vector<int>v(10);
return dfs(len,v,1,1);
}
void solve(){
int l=read(),r=read(),ans=0;
if(r==1e18)r--,ans+=18;
ans+=num_dp(r);
if(l)ans-=num_dp(l-1);
cout<<ans<<'\n';
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
\(D. Darkness II\)
将一个矩形的可以是他与别的矩阵相连的部分拆分成若干矩阵查询。然后对每个遍历一遍,能连的就连上,那么每个矩阵可以看做只会被扩展一次。
\(code from jiangly\)
vector<array<int,4> >rect;
vector<bool>vis;
vector<int>f[1<<20],g[1<<20];
void add(int p,int l,int r,int yl,int yr,int i){
if(l>=yr||r<=yl){
return;
}
f[p].push_back(i);
if(l>=yl&&r<=yr){
g[p].push_back(i);
return ;
}
int m=(l+r)/2;
add(2*p,l,m,yl,yr,i);
add(2*p+1,m,r,yl,yr,i);
}
int query(int p,int l,int r,int yl,int yr,int xl){
if(l>=yr||r<=yl){
return -1;
}
while(!f[p].empty()&&vis[f[p].back()])
f[p].pop_back();
while(!g[p].empty()&&vis[g[p].back()])
g[p].pop_back();
if(!g[p].empty()&&xl<=rect[g[p].back()][1])
return g[p].back();
if(l>=yl&&r<=yr){
if(!f[p].empty()&&xl<=rect[f[p].back()][1])
return f[p].back();
return -1;
}
int m=(l+r)/2;
int res=query(2*p,l,m,yl,yr,xl);
if(res==-1){
res=query(2*p+1,m,r,yl,yr,xl);
}
return res;
}
void solve(){
int n=read();
vector<pair<int,int> >a(n);
vector<int>v;
for(int i=0;i<n;i++){
int x=read(),y=read();
a[i]=make_pair(x,y);
v.push_back(y-1);
v.push_back(y);
v.push_back(y+1);
v.push_back(y+2);
}
sort(a.begin(),a.end());
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
int m=v.size();
for(int i=0;i<n;i++){
auto [x,y]=a[i];
int yl=lower_bound(v.begin(),v.end(),y)-v.begin();
int yr=lower_bound(v.begin(),v.end(),y+1)-v.begin();
int xl=x,xr=x+1;
while(1){
int j=query(1,0,m,yl-1,yr+1,xl);
if(j==-1){
j=query(1,0,m,yl,yr,xl-1);
}
if(j==-1){
j=query(1,0,m,yl-2,yr+2,xl+1);
}
if(j==-1){
break;
}
vis[j]=true;
xl=min(xl,rect[j][0]);
yl=min(yl,rect[j][2]);
yr=max(yr,rect[j][3]);
}
add(1,0,m,yl,yr,rect.size());
rect.push_back({xl,xr,yl,yr});
vis.push_back(false);
}
int ans=0;
for(int i=0;i<rect.size();i++){
if(!vis[i]){
auto [xl,xr,yl,yr]=rect[i];
ans+=(xr-xl)*(v[yr]-v[yl]);
}
}
cout<<ans<<'\n';
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
\(E. Inverse Counting Path\)
这题采用六进制构造数字,对于每个需要的次数连接到总路线上,对于需要的当前位的个数,加粗相应的一段连接路的宽度。
int a[N][N];
void solve(){
int n=read();
vector<int>ans;
while(n){
ans.push_back(n%6);
n/=6;
}
cout<<"30\n";
for(int i=1;i<=30;i++){
a[i][30]=a[30][i]=1;
}
for(int i=0;i<12;i++){
for(int j=1;j<=3;j++){
for(int k=1;k<=3;k++){
a[i*2+j][i*2+k]=1;
}
}
}
for(int i=0;i<ans.size();i++){
int k=i*2+1;
if(i&1){
if(ans[i]>0){
for(int j=k;j<=30;j++){
a[j][k]=1;
}
}
for(int j=30-ans[i]+1;j<=30;j++){
a[j][k+1]=1;
}
}else{
if(ans[i]>0){
for(int j=k;j<=30;j++){
a[k][j]=1;
}
}
for(int j=30-ans[i]+1;j<=30;j++){
a[k+1][j]=1;
}
}
}
for(int i=1;i<=30;i++){
for(int j=1;j<=30;j++){
cout<<a[i][j]<<" ";
}
cout<<'\n';
}
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
- Programming Collegiate Provincial Contest Hubeiprogramming collegiate provincial contest programming collegiate provincial shandong programming provincial collegiate sichuan programming collegiate provincial guangdong programming provincial collegiate shandong programming collegiate provincial counting programming provincial collegiate sponsored 2023 programming collegiate provincial 题解programming collegiate provincial programming collegiate jiangsu contest