文章目录
- A. Comparing Two Long Integers
- B. Dinner with Emma
- C. The Labyrinth
- D. Longest k-Good Segment
- E. Sum of Remainders
A. Comparing Two Long Integers
模拟,签到。
#include <bits/stdc++.h>using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;void solve()
{string a,b;cin>>a>>b;int i1=0,i2=0;while(a[i1]=='0') i1++;while(b[i2]=='0') i2++;int s1=a.size()-i1;int s2=b.size()-i2;if(s1!=s2){if(s1>s2) cout<<">"<<endl;else cout<<"<"<<endl;}else{for(int i=i1,j=i2;i<a.size();i++){if(a[i]>b[j]){cout<<">"<<endl;return ;}else if(a[i]<b[j]){cout<<"<"<<endl;return ;}j++;}cout<<"="<<endl;}
}int main()
{ios::sync_with_stdio(0);cin.tie(0);int t = 1;// cin >> t;while (t--){solve();}system("pause");return 0;
}
B. Dinner with Emma
签到。
#include <bits/stdc++.h>using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;int a[205][205];void solve()
{int n,m;cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>a[i][j];}}int ans=0;for(int i=1;i<=n;i++){int res=2e9;for(int j=1;j<=m;j++) res=min(res,a[i][j]);ans=max(ans,res);}cout<<ans<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);int t = 1;// cin >> t;while (t--){solve();}system("pause");return 0;
}
C. The Labyrinth
BFS,和edu第一场的D题感觉有异曲同工之妙,这题初看以为是对障碍物进行bfs,实则是对点进行bfs。
#include <bits/stdc++.h>using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;char a[2005][2005];
int d[2005][2005];
int st[2005][2005];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int n,m;
void bfs(int x,int y)
{queue<pll >q;st[x][y]=1;set<pll> v;q.push({x,y});int cnt=1;while(!q.empty()){auto [nx,ny]=q.front();q.pop();for(int i=0;i<4;i++){int zx=nx+dx[i],zy=ny+dy[i];if(st[zx][zy]) continue;if(a[zx][zy]=='*'){v.insert({zx,zy});continue;}if(zx<1||zx>n||zy<1||zy>m) continue;cnt++;st[zx][zy]=1;q.push({zx,zy});}}for(auto [x,y]: v) d[x][y]+=cnt;
}void solve()
{cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) cin>>a[i][j];}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i][j]=='.'&&!st[i][j]){bfs(i,j);}}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i][j]=='*'){cout<<(d[i][j]+1)%10;}else cout<<".";}cout<<endl;}
}int main()
{ios::sync_with_stdio(0);cin.tie(0);int t = 1;while (t--){solve();}system("pause");return 0;
}
D. Longest k-Good Segment
双指针
#include <bits/stdc++.h>using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;void solve()
{int n,k;cin>>n>>k;vector<int> a(n+5);for(int i=1;i<=n;i++) cin>>a[i];map<int,int> mp;int ans=0;int l=0,r=0;for(int i=1,j=1;i<=n;i++){mp[a[i]]++;while(mp.size()>k&&j<=n) {mp[a[j]]--;if(mp[a[j]]==0) mp.erase(a[j]);j++;}if(ans<i-j+1){l=j,r=i;ans=i-j+1;}}cout<<l<<" "<<r<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);int t = 1;// cin >> t;while (t--){solve();}system("pause");return 0;
}
E. Sum of Remainders
整数分块。
对于 n m o d m n\mod m nmodm的形式,我们相求求余数,那么可以把式子转化为 n − ⌊ n m ⌋ × m n-\lfloor {n \over m} \rfloor \times m n−⌊mn⌋×m的形式,那么此题就转化为了 ∑ i = 1 m n − ⌊ n i ⌋ × i \sum_{i=1}^m{n-\lfloor {n \over i} \rfloor \times i} i=1∑mn−⌊in⌋×i
对于公式的前半部分,我们可以直接求出,答案为 n × m n\times m n×m,对于公式后半部分,我们可以运用整数分块的相关知识。
整数分块:
用于快速计算 ∑ i = s t e d ⌊ n i ⌋ \sum_{i=st}^{ed} {\lfloor {n \over i} \rfloor } ∑i=sted⌊in⌋的方法我们称为整数分块,因为计算机是进行向下取整的,所以在一段区间里面我们就会得到一些相同的值,所以对于这些区间里面的点,我们没有必要进行重复计算。只需要计算一遍即可。
显然,存在一个 k k k,使得 ⌊ n k ⌋ = l \lfloor {n \over k} \rfloor=l ⌊kn⌋=l
令 r = ⌊ n k ⌋ r=\lfloor {n \over k} \rfloor r=⌊kn⌋
显然对于 ⌊ n i ⌋ = ⌊ n j ⌋ ( l ≤ i ≤ r ) \lfloor {n \over i} \rfloor=\lfloor {n \over j} \rfloor(l\leq i \leq r) ⌊in⌋=⌊jn⌋(l≤i≤r)
那么我们对于给定的区间,枚举每个 l l l即可。
// for(int i = st;i<=ed;i++)ans+=num/i
int block(int st, int ed, int num) {int L = 0;int _ans = 0;ed = min(ed, num);for (int i = st; i <= ed; i = L + 1) {L = min(ed,num / (num / i)); //该区间的最后一个数_ans += (L - i + 1)*(num / i);//区间[i,L]的num/i 都是一个值}return _ans;
}
对于此题,我们对整数分块的板子进行修改一下即可。
#include <bits/stdc++.h>using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 1e9+7;
const int maxv = 4e6 + 5;ll inv2;ll qmi(ll a,ll b,ll c)
{ll res=1;while(b){if(b%2){res=res*a%c;}b>>=1;a=a*a%c;}return res;
}ll cal(ll l,ll r)
{ll res=((((l+r)%mod)*((r-l+1)%mod))%mod*inv2)%mod;return res;
}ll block(ll st,ll ed,ll n)
{ll res=0;ll l=0;ed=min(ed,n);for(ll i=st;i<=ed;i=l+1){l=min(ed,n/(n/i));res=(res+cal(i,l)*(n/i))%mod;}return res;
}void solve()
{inv2=qmi(2,mod-2,mod);//cout<<inv2<<endl;ll n,m;cin>>n>>m;ll ans=(n%mod)*(m%mod)%mod;//cout<<block(1,m,n)<<endl;ans=(ans-block(1,m,n)%mod+mod)%mod;cout<<ans<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);int t = 1;// cin >> t;while (t--){solve();}system("pause");return 0;
}