文章目录
- [A. Difficult Contest](#A. Difficult Contest)
- [B. Left and Down](#B. Left and Down)
- [C. Count Good Numbers](#C. Count Good Numbers)
- [D. Segments Covering](#D. Segments Covering)
A. Difficult Contest
让字母T在最前面就行,排序一下然后翻转字符串。
cpp
#include<bits/stdc++.h>
#define LL long long
using namespace std;
typedef pair<int,int> PII;
void solve(){
string s;
cin>>s;
int n=s.size();
bool ok=0;
for(int i=0;i+2<n;i++){
if(s[i]=='F' && s[i+1]=='F' && s[i+2]=='T') ok=1;
if(s[i]=='N' && s[i+1]=='T' && s[i+2]=='T') ok=1;
}
if(!ok){
cout<<s<<'\n';
}else{
sort(s.begin(),s.end());
reverse(s.begin(),s.end());
cout<<s<<'\n';
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
B. Left and Down
显然答案只有1或者2。
对于1,那就是重复某对 ( d x , d y ) (dx,dy) (dx,dy),因为对 d x , d y dx,dy dx,dy有范围限制,显然是让 d x , d y dx,dy dx,dy越小越好,于是就有 d x = x / g c d ( x , y ) , d y = y / g c d ( x , y ) dx=x/gcd(x,y),dy=y/gcd(x,y) dx=x/gcd(x,y),dy=y/gcd(x,y),观察样例3也能发现,重复次数就是 g c d ( x , y ) gcd(x,y) gcd(x,y),最后需要判断 d x < = k & & d y < = k dx<=k \&\&dy<=k dx<=k&&dy<=k。
对于2,那就是 ( 1 , 0 ) (1,0) (1,0)和 ( 0 , 1 ) (0,1) (0,1)重复操作。
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
void solve(){
int a,b,k;
cin>>a>>b>>k;
int gcd=__gcd(a,b);
a/=gcd,b/=gcd;
if(a<=k && b<=k){
cout<<1<<'\n';
}else{
cout<<2<<'\n';
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
C. Count Good Numbers
要去掉所有含个位数质数因子,其实就只有 2 , 3 , 5 , 7 2,3,5,7 2,3,5,7,所以简单容斥一下。
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
int calc(int x){
int ans=0;
ans+=x/2;
ans+=x/3;
ans+=x/5;
ans+=x/7;
ans-=x/6;
ans-=x/10;
ans-=x/14;
ans-=x/15;
ans-=x/21;
ans-=x/35;
ans+=x/30;
ans+=x/42;
ans+=x/70;
ans+=x/105;
ans-=x/210;
return x-ans;
}
void solve(){
int l,r;
cin>>l>>r;
// cout<<calc(11)<<'\n';
cout<<calc(r)-calc(l-1)<<'\n';
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
D. Segments Covering
考虑 d p dp dp, d p i dp_i dpi表示仅覆盖前 i i i个单元格的概率
对于 l = 1 l=1 l=1的线段, d p r dp_r dpr需要加上(当前线段发生的概率 ∗ * ∗其他线段都不发生的概率),我用 s u m sum sum表示所有线段都不发生的概率,这样可以快速求出其他线段都不发生的概率。
对于 l ! = 1 l!=1 l!=1的线段,我用概率 q q q表示 d p l − 1 dp_{l-1} dpl−1,首先 q q q要除以它不发生的概率(因为前面求 l = 1 l=1 l=1的线段时乘上了其他线段都不发生的概率),然后 q q q再乘上它发生的概率(表示它发生了),再加上 d p r dp_r dpr。
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+10,mod=998244353;
int n,m;
int qmi(int a,int b) {
int res=1;
while(b) {
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
struct node {
int l,r,p;
bool operator<(const node& t)const {
if(l==t.l) return r<t.r;
return l<t.l;
}
} seg[N];
int dp[N];
void solve() {
cin>>n>>m;
int sum=1;
for(int i=1; i<=n; i++) {
int l,r,x,y;
cin>>l>>r>>x>>y;
int t=x*qmi(y,mod-2)%mod;
sum=sum*((1-t+mod)%mod)%mod;
seg[i]= {l,r,t};
}
sort(seg+1,seg+n+1);
for(int i=1;i<=n;i++){
auto [l,r,p]=seg[i];
int j=l-1;
if(j!=0) {
int q=dp[j];
int pp=q*qmi(((1-p+mod)%mod),mod-2)%mod;
pp=pp*p%mod;
dp[r]=(dp[r]+pp)%mod;
}else{
int pp=sum*qmi(((1-p+mod)%mod),mod-2)%mod;
pp=pp*p%mod;
dp[r]=(dp[r]+pp)%mod;
}
}
cout<<dp[m]<<'\n';
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
// cin>>T;
while(T--) {
solve();
}
return 0;
}