- 1809C 神必构造题 对子数组的和考虑使用前缀和,发现逆序对的规律,构造
- 1797C 神奇交互题 需要找特殊的点确定位置
- 2132D 神奇数位题 需要用二分logk优化复杂度,把数位转换成能到的上限数aim
1809C 构造 前缀和 逆序对 思维 排序 1500
/*
神必构造题
连续子数组和-> 前缀和sj-si
和为正i>j,si>sj
和为负i>j,si<sj
问题转化成构造前缀和数组
k个正和,其他的负和,即k个正序对,其他的都是逆序对
在逆排序中怎么搞出正序对?
排序,一次交换就得一个正序对
*/
void solve(){int n,k;cin>>n>>k;vector<int>a(n+1);forr(i,0,n){a[i]=n-i+1;//生成逆序}forr(i,0,n){forr(j,i+1,n){if(k){k--;//不用判断 前面的一定是大的数,确定好的位置才是产生正序对的最小的数swap(a[j],a[i]);//插入排序 把小的往前面放,形成逆序对}}}forr(i,0,n-1){cout<<a[i+1]-a[i]<<' ';}cout<<endl;// forr(i,1,n)cout<<a[i]+b[i]<<' ';cout<<endl;
}
1797C 思维 交互 1600
参考dalao题解
void solve(){int n,m;cin>>n>>m;int a,b;cout<<"? 1 1\n";fls;cin>>a;cout<<"? 1 "<<m<<endl;fls;cin>>b;// cout<<a<<' '<<b<<endl;int tp;if(a+b==m-1){cout<<"? 1 "<<a+1<<endl;fls;cin>>tp;cout<<"! "<<tp+1<<' '<<a+1<<endl;fls;}else{cout<<"? "<<min(a,b)+1<<' '<<1<<endl;fls;cin>>tp;cout<<"! "<<min(a,b)+1<<' '<<1+tp<<endl;fls;}
}
2132D 数位dp+二分 1600
累死我了
数位求和使用数位dp
const int N=16,M=150,mod=998244353;
//dcnt[i]是数到i位9999...有多少数位 前缀和
int ncnt[N],dcnt[N],ten[N];
/*
dp[pos][limit][sum]
sum是本状态到底层要返回的数位和
*/
int dp[N][2][M];
void solve(){int k;cin>>k;int dig=lower_bound(dcnt+1,dcnt+16,k)-dcnt;//在前缀和中二分 到k个数有dig位// cout<<dig<<endl;int aim=ten[dig-1]-1;//到dig-1位999...k-=dcnt[dig-1];//剩下的长度// cout<<k<<endl;int tp=k/dig;aim+=tp;//继续分到dig位中k%=dig;// cout<<aim<<endl;memset(dp,-1,sizeof dp);string n=to_string(aim);auto dfs=[&](auto&& self,int pos,int limit,int sm)->int{if(pos==n.size())return sm;if(dp[pos][limit][sm]>=0)return dp[pos][limit][sm];int ans=0;int up=(limit?n[pos]-'0':9);forr(i,0,up){ans+=self(self,pos+1,limit&&i==up,sm+i);}return dp[pos][limit][sm]=ans;};int ans=dfs(dfs,0,1,0);// cout<<ans<<endl;//补全剩下的string nxt=to_string(aim+1);forr(i,0,k-1)ans+=(nxt[i]-'0');cout<<ans<<endl;}
signed main()
{ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);ten[0]=1,ncnt[1]=10,dcnt[1]=9;forr(i,2,15){ncnt[i]=ncnt[i-1]*9;dcnt[i]=ncnt[i]*i+dcnt[i-1];ncnt[i]+=ncnt[i-1];}// forr(i,1,15)cout<<dcnt[i]<<' ';cout<<endl;forr(i,1,15){ten[i]=ten[i-1]*10;}int t=1;cin>>t;while(t--) solve();}