【学习笔记】ARC149

Two LIS Sum

结论是,其中一个序列的 L I S LIS LIS一定是 n n n这结论为啥我还想了半天啊

Avoid Prime Sum

简单构造题。分 n n n的奇偶性讨论,上半部分全填奇数,下半部分全填偶数,中间对于奇偶数的分界线,可以考虑填 i i i 2 i 2i 2i就是场上花的时间有点长

#include<bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back using namespace std; int n,a[1005][1005],vis[1000005]; vector<int>v1,v2,v3,v4; signed main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); cin>>n; if(n==3){ cout<<"1 3 5\n8 6 9\n4 2 7"; return 0; } if(n==4){ cout<<"15 11 16 12\n13 3 6 9\n14 7 8 1\n4 2 10 5"; return 0; } if(n%2==0){ for(int i=1;i<=n;i++){ a[n/2][i]=i*2+1; a[n/2+1][i]=i*4+2; vis[i*2+1]=vis[i*4+2]=1; } for(int i=1;i<=n*n;i++){ if(!vis[i]){ if(i%2)v1.pb(i); else v2.pb(i); } }for(int i=1;i<n/2;i++){ for(int j=1;j<=n;j++){ a[i][j]=v1.back();v1.pop_back(); } } for(int i=n/2+2;i<=n;i++){ for(int j=1;j<=n;j++){ a[i][j]=v2.back();v2.pop_back(); } } } else { a[n/2+1][n/2+1]=9,a[n/2][n/2]=3; a[n/2+1][n/2]=6,a[n/2+2][n/2+1]=18; vis[9]=vis[3]=vis[6]=vis[18]=1; for(int i=1;i<=n;i++){ if(!vis[i*2+1])v3.pb(i*2+1),vis[i*2+1]=vis[i*4+2]=1; } for(int i=1;i<n/2;i++){ a[n/2][i]=v3.back(),a[n/2+1][i]=v3.back()*2;v3.pop_back(); } for(int i=n/2+2;i<=n;i++){ a[n/2+1][i]=v3.back(),a[n/2+2][i]=v3.back()*2;v3.pop_back(); } for(int i=1;i<=n*n;i++){ if(!vis[i]){ if(i%2)v1.pb(i); else v2.pb(i); } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(!a[i][j]){ if(i<=n/2)a[i][j]=v1.back(),v1.pop_back(); else a[i][j]=v2.back(),v2.pop_back(); } } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cout<<a[i][j]<<' '; }cout<<endl; } }

Simultaneous Sugoroku

考场上根本没时间想。。。

对于起点是 1 ∼ 1 0 6 1\sim 10^6 1106的每个点,如果当前 x > 0 x>0 x>0那么往左走 d d d步,如果 x < 0 x<0 x<0那么往右走 d d d步,如果走到 0 0 0就停下来。

观察这个运动过程。如果某一时刻两个数移动到了 x x x − x -x x的位置,那么接下来他们的移动都是对称的,也就是说是一对相关性的点。

所以只维护原点左侧或右侧的点即可。复杂度 O ( m + max ⁡ ( w i ) ) O(m+\max(w_i)) O(m+max(wi))

#include<bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back using namespace std; int n,m,l=1,X[1000005],fa[1000005],res[1000005],mx[1000005]; deque<int>q; void dfs(int x){ if(~mx[x])return;dfs(fa[x]); if(mx[fa[x]])mx[x]=1,res[x]=res[fa[x]]; else mx[x]=0,res[x]=-res[fa[x]]; } int main(){ cin>>n>>m;int tmp=0;for(int i=1;i<=n;i++)cin>>X[i],tmp=max(tmp,X[i]);memset(mx,-1,sizeof mx); for(int i=1;i<=tmp;i++)q.push_back(i); for(int i=1;i<=m;i++){ int d;cin>>d;if(l>0)l-=d;else l+=d; int r=l+q.size()-1; if(l<=0&&r>=0){ mx[q[abs(l)]]=1,res[q[abs(l)]]=i; if(abs(l)<=abs(r)){ for(int j=0;j<abs(l);j++){ fa[q[j]]=q[2*abs(l)-j]; }for(int j=0;j<=abs(l);j++)q.pop_front();l=1; } else { for(int j=0;j<abs(r);j++){ fa[q[q.size()-j-1]]=q[2*abs(l)-q.size()+j+1]; }for(int j=0;j<=abs(r);j++)q.pop_back(); } } } for(int i=0;i<q.size();i++){ mx[q[i]]=0,res[q[i]]=l+i; } for(int i=1;i<=n;i++){ dfs(X[i]);if(mx[X[i]])cout<<"Yes"<<' '<<res[X[i]]<<endl; else cout<<"No"<<' '<<res[X[i]]<<endl; } }

Sliding Window Sort

首先这个排序过程很不舒服

考虑将序列固定成每次只对前 m m m个数排序。每次排序完序列整体左移一位。

对于一个序列,我们可以把它看成两个部分,注意到前 m − 1 m-1 m1个数始终有序,并且每次会把最小的那个数弹出到序列末尾,而后 n − m + 1 n-m+1 nm+1个数始终在往前移位。

显然 K > n − m + 1 K>n-m+1 K>nm+1过后左右两部分的集合就不会发生变化了。考虑从最终序列右一半入手,记作 { x i } \{x_i\} {xi}。记初始序列 { a i } ( b i ) \{a_i\}(b_i) {ai}(bi)。注意到如果 x i − 1 > x i x_{i-1}>x_i xi1>xi那么 b i = x i b_i=x_i bi=xi

注意到忽略上述确定的值后 { x i } \{x_i\} {xi} { b i } \{b_i\} {bi}均为递增,问题转述为每次排序的 m m m个数中都有最小值 b i b_i bi,那么合法的 { a i } ( b i ) \{a_i\}(b_i) {ai}(bi)数目为 m l e n × ( m − 1 ) ! m^{len}\times (m-1)! mlen×(m1)

如果 K < n − m + 1 K<n-m+1 K<nm+1那么把多余的数删掉即可。

复杂度 O ( n ) O(n) O(n)

我信仰什么,我便实现哪种方法。

#include<bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back using namespace std; const int mod=998244353; int n,m,K,a[600005]; ll fpow(ll x,ll y){ ll z(1); for(;y;y>>=1){ if(y&1)z=z*x%mod; x=x*x%mod; }return z; } int main(){ cin>>n>>m>>K; for(int i=0;i<n;i++)cin>>a[i]; if(K<n-m+1)n-=n-m+1-K;for(int i=0;i<n;i++)a[i+n]=a[i]; vector<int>vec(a+K%n,a+K%n+n);K%=n-m+1; vector<int>vec2=vec;sort(vec2.begin(),vec2.end()); for(auto &x:vec)x=lower_bound(vec2.begin(),vec2.end(),x)-vec2.begin()+1; for(int i=0;i<m-1;i++){ if(vec[i]!=n-m+2+i){ cout<<0;return 0; } } vec.erase(vec.begin(),vec.begin()+m-1); for(int i=0;i<n-m+1;i++)vec.pb(vec[i]); vector<int>vec3(vec.begin()+n-m+1-K,vec.begin()+n-m+1-K+n-m+1); int len=n-m+1,x=vec3[0]; for(int i=1;i<vec3.size();i++){ if(vec3[i]<x)len--; else x=vec3[i]; } ll res=fpow(m,len);for(int i=1;i<=m-1;i++)res=res*i%mod; cout<<res; }

Rational Number System

咕咕咕。。。


__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530095.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(12)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2021-10-04 【题解】CF1097D Makoto and a Blackboard
2021-10-04 【题解】关于 bzoj 4318 的推广
点击右上角即可分享
微信分享提示