title : 2022 年远光杯程序设计竞赛
date : 2022-6-2
tags : ACM,题解,练习记录
author : Linno
2022 年远光杯程序设计竞赛
题目链接:https://oj.kexie.club/problems
补题进度:9/12
打了个10*10的表,然后发现只需要确定m=1和m=n-1的情况即可。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
map<int,string>mp[20];
int n,m;
void Solve(){mp[1][0]="MUST";
mp[1][1]="IMPOSSIBLE";
mp[2][0]="MUST";
mp[2][1]="IMPOSSIBLE";
mp[2][2]="MUST";
mp[3][0]="MUST";
mp[3][1]="IMPOSSIBLE";
mp[3][2]="MAYBE";
mp[3][3]="IMPOSSIBLE";
mp[4][0]="MUST";
mp[4][1]="IMPOSSIBLE";
mp[4][2]="MAYBE";
mp[4][3]="IMPOSSIBLE";
mp[4][4]="MUST";
mp[5][0]="MUST";
mp[5][1]="IMPOSSIBLE";
mp[5][2]="MAYBE";
mp[5][3]="MAYBE";
mp[5][4]="MAYBE";
mp[5][5]="IMPOSSIBLE";
mp[6][0]="MUST";
mp[6][1]="IMPOSSIBLE";
mp[6][2]="MAYBE";
mp[6][3]="MAYBE";
mp[6][4]="MAYBE";
mp[6][5]="IMPOSSIBLE";
mp[6][6]="MUST";
mp[7][0]="MUST";
mp[7][1]="IMPOSSIBLE";
mp[7][2]="MAYBE";
mp[7][3]="MAYBE";
mp[7][4]="MAYBE";
mp[7][5]="MAYBE";
mp[7][6]="MAYBE";
mp[7][7]="IMPOSSIBLE";
mp[8][0]="MUST";
mp[8][1]="IMPOSSIBLE";
mp[8][2]="MAYBE";
mp[8][3]="MAYBE";
mp[8][4]="MAYBE";
mp[8][5]="MAYBE";
mp[8][6]="MAYBE";
mp[8][7]="IMPOSSIBLE";
mp[8][8]="MUST";
mp[9][0]="MUST";
mp[9][1]="IMPOSSIBLE";
mp[9][2]="MAYBE";
mp[9][3]="MAYBE";
mp[9][4]="MAYBE";
mp[9][5]="MAYBE";
mp[9][6]="MAYBE";
mp[9][7]="MAYBE";
mp[9][8]="MAYBE";
mp[9][9]="IMPOSSIBLE";
mp[10][0]="MUST";
mp[10][1]="IMPOSSIBLE";
mp[10][2]="MAYBE";
mp[10][3]="MAYBE";
mp[10][4]="MAYBE";
mp[10][5]="MAYBE";
mp[10][6]="MAYBE";
mp[10][7]="MAYBE";
mp[10][8]="MAYBE";
mp[10][9]="IMPOSSIBLE";
mp[10][10]="MUST";
cin>>n>>m;
if(n<=10){
cout<<mp[n][m]<<"\n";
}else{
if(m==0) cout<<"MUST\n";
else if(m==1) cout<<"IMPOSSIBLE\n";
else if(m==n){
if(n&1) cout<<"IMPOSSIBLE\n";
else cout<<"MUST\n";
}else if(m==n-1){
if(n&1) cout<<"MAYBE\n";
else cout<<"IMPOSSIBLE\n";
}else cout<<"MAYBE\n";
}
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}
没写
没写
又可以打表。然后差分一下发现是欧拉函数。结果就是4×sum[n-1],其中sum为欧拉函数前缀和。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=5e6+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
int n,phi[N],np[N],pri[N],sum[N],cnt=0;
void Get_phi(){
phi[1]=1;
for(int i=2;i<N;i++){
if(!np[i]){
pri[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt&&i*pri[j]<N;j++){
np[i*pri[j]]=1;
if(i%pri[j]==0){
phi[i*pri[j]]=pri[j]*phi[i]; //可以手动证一下
break;
}else phi[i*pri[j]]=(pri[j]-1)*phi[i]; //互质,积性
}
}
sum[0]=0;
for(int i=1;i<N;++i) sum[i]=sum[i-1]+phi[i];
}
void Solve(){
Get_phi();
cin>>n;
cout<<4ll*sum[n-1]<<"\n";
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
// cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}
签到。ceil()向上取整。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
void Solve(){
double s;
cin>>s;
cout<<ceil(s/60.0)<<"\n";
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
// cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}
没写。
一看式子就知道是矩阵快速幂裸题。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
struct Mat{
int a[2][2];
Mat(){memset(a,0,sizeof(a));}
Mat(int x){
a[0][0]=a[1][1]=1;
a[0][1]=a[1][0]=0;
}
Mat operator *(const Mat b){
Mat res;
for(int i=0;i<2;++i){
for(int j=0;j<2;++j){
for(int k=0;k<2;++k){
res.a[i][j]+=a[i][k]*b.a[k][j]%mod;
res.a[i][j]%=mod;
}
}
}
return res;
}
};
inline Mat fpow(Mat a,int b){
Mat res(1);
while(b){
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
void Solve(){
int n,a,b,A0,B0;
cin>>n>>a>>b;
cin>>A0>>B0;
Mat bas,ans;
bas.a[0][0]=a-1;
bas.a[0][1]=a;
bas.a[1][0]=b;
bas.a[1][1]=b-1;
ans.a[0][0]=A0;
ans.a[1][0]=B0;
ans=fpow(bas,n)*ans;
cout<<ans.a[0][0]%mod<<"\n";
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}
注意审题。首先得判一下子树是否符合BST,然后再判高度差。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int N=5e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
struct node{
int ch[2],fa,sz,val,mi,mx,hg,tg; //hg:高度,tg:是否满足BST性质 ,fg:是否满足avl性质
}tr[N];
#define ls(x) tr[x].ch[0]
#define rs(x) tr[x].ch[1]
#define val(x) tr[x].val
#define fa(x) tr[x].fa
#define sz(x) tr[x].sz
#define hg(x) tr[x].hg
#define tg(x) tr[x].tg
#define mx(x) tr[x].mx
#define mi(x) tr[x].mi
int n,ans=1;
inline void dfs1(int x){
mx(x)=mi(x)=val(x);
if(ls(x)){dfs1(ls(x));mx(x)=max(mx(x),mx(ls(x)));mi(x)=min(mi(x),mi(ls(x)));}
if(rs(x)){dfs1(rs(x));mx(x)=max(mx(x),mx(rs(x)));mi(x)=min(mi(x),mi(rs(x)));}
sz(x)=sz(ls(x))+sz(rs(x))+1;
hg(x)=max(hg(ls(x)),hg(rs(x)))+1; //非叶子结点
tg(x)=tg(ls(x))|tg(rs(x));
tg(x)|=(abs(hg(ls(x))-hg(rs(x)))>1);
if(ls(x)&&mx(ls(x))>val(x)) tg(x)=1;
if(rs(x)&&mi(rs(x))<val(x)) tg(x)=1;
if(!tg(x)) ans=max(ans,sz(x));
//cout<<x<<" "<<hg(x)<<" "<<tg(x)<<"\n";
}
void Solve(){
cin>>n;
for(int i=1;i<=n;++i){
cin>>tr[i].val;
tr[i].mx=tr[i].mi=val(i);
}
for(int i=1,u,v,w;i<n;++i){
cin>>u>>v>>w;
tr[u].ch[w]=v;
tr[v].fa=u;
}
for(int i=1;i<=n;++i){
if(!tr[i].fa){ //根节点
dfs1(i);
cout<<ans<<"\n";
return;
}
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("2.in.txt","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
// cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}
显然答案只有1、2、3三种,逐个判一下即可。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
int n,q,cnt[205];
string str;
inline bool check(int x,int y){
if('a'<=str[x-1]&&str[x-1]<='z'&&'a'<=str[y-1]&&str[y-1]<='z') return 1;
else if('A'<=str[x-1]&&str[x-1]<='Z'&&'A'<=str[y-1]&&str[y-1]<='Z') return 1;
else if(abs(str[x-1]-str[y-1])==32) return 1;
return 0;
}
inline bool chk2(int x,int y){
if('a'<=str[x-1]&&str[x-1]<='z'&&cnt[str[x-1]-32]) return 1;
if('A'<=str[x-1]&&str[x-1]<='Z'&&cnt[str[x-1]+32]) return 1;
if('a'<=str[y-1]&&str[y-1]<='z'&&cnt[str[y-1]-32]) return 1;
if('A'<=str[y-1]&&str[y-1]<='Z'&&cnt[str[y-1]+32]) return 1;
return 0;
}
void Solve(){
cin>>n>>q;
cin>>str;
for(int i=0;i<n;++i) ++cnt[str[i]];
for(int i=1,x,y;i<=q;++i){
cin>>x>>y;
if(check(x,y)||abs(x-y)==1){
cout<<1<<"\n";
}else if(check(x+1,y)||check(x-1,y)||check(x,y+1)||check(x,y-1)||abs(x-y)==2){
cout<<2<<"\n";
}else if(chk2(x,y)){ //x或者y位置的字符存在大小写表示
cout<<2<<"\n";
}else cout<<3<<"\n";
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
// cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}
链表维护一下即可。但估计我是全场唯一一个FHQ Treap了。
#include<bits/stdc++.h>
//#define int long long
#define ls(x) (T[x].ch[0])
#define rs(x) (T[x].ch[1])
#define sz(x) (T[x].sz)
#define val(x) (T[x].val)
#define pri(x) (T[x].pri)
#define fa(x) (T[x].fa)
using namespace std;
const int N=2e5+7;
int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
struct FHQ{
int ch[2],val,pri,sz,fa;
}T[N];
int n,m,root=0,tot,id[N];
void update(int x){
T[x].sz=sz(ls(x))+sz(rs(x))+1;
}
bool get(int x){
return rs(fa(x))==x;
}
int cre(int v){ //新开辟一个结点
sz(++tot)=1;
val(tot)=v;
pri(tot)=rand();
id[v]=tot;
return tot;
}
int merge(int x,int y){ // 合并操作
if(!x||!y) return x+y; //x和y中必定有一个是0
if(pri(x)<pri(y)){ //比较两棵树根的随机权值
rs(x)=merge(rs(x),y); //把x加到左边的树上
fa(rs(x))=x;
update(x); //更新大小
return x;
}else{
ls(y)=merge(x,ls(y));
fa(ls(y))=y;
update(y);
return y;
}
}
void split(int x,int k,int &a,int &b,int faa=0,int fab=0){
if(x==0){a=b=0;return;}
if(k<=sz(ls(x))) fa(x)=fab,b=x,split(ls(x),k,a,ls(x),faa,x);
else fa(x)=faa,a=x,split(rs(x),k-sz(ls(x))-1,rs(x),b,x,fab);
update(x);
}
int find(int k){
int node=k,res=sz(ls(k))+1;
while(node!=root&&k){
if(get(k)) res+=sz(ls(fa(k)))+1;
k=fa(k);
}
return res;
}
void Solve(){
n=read();m=read();
int x,y,z,w,s,t,k;
for(int i=1;i<=n;i++){ //插入
s=read();
split(root,i-1,x,y);
root=merge(merge(x,cre(s)),y);
}
// for(int i=1;i<=n;++i) cout<<i<<" "<<id[i]<<" "<<find(id[i])<<"!!\n";
for(int i=1,x,y,l,r;i<=m;i++){
x=read();y=read();
l=find(id[x]);
r=find(id[y]);
//cout<<id[x]<<" "<<id[y]<<" "<<l<<" "<<r<<"!!\n";
split(root,r,x,y);
split(x,l-1,x,z); //x->z->y
root=merge(merge(x,y),z);
}
for(int i=n,node;i>=1;--i){
split(root,i,x,y);
node=x;
while(rs(node)) node=rs(node);
printf("%lld",val(node));
if(i==1) putchar('\n');
else putchar(' ');
root=merge(x,y);
}
}
signed main(){
srand(time(0));
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
// cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}
「2022 远光杯」双端队列
如题目所说,直接用双端队列模拟一下这个过程即可。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int N=2e6+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
int n,a[N],pos[N];
deque<int>dq;
void Solve(){
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i],pos[a[i]]=i;
while(dq.size()) dq.pop_front();
dq.push_back(1);
// lf=rg=1;
for(int i=2;i<=n;++i){
if(pos[i]<pos[i-1]) dq.push_front(i);
else dq.push_back(i);
}
for(int i=1;i<=n;++i){
if(a[i]!=dq.front()){
cout<<"NO\n";
return;
}
dq.pop_front();
}
cout<<"YES\n";
/*
while(dq.size()){
cout<<dq.front()<<" ";
dq.pop_front();
}*/
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}
母线长度/爬升能力就是汽车运动的总时间,乘以线速度就是他的总路程。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
void Solve(){
double h,r,s,v;
cin>>h>>r>>s>>v;
double mu=sqrt(h*h+r*r);
double t=mu/s;
double sum=t*v;
printf("%.10lf\n",sum);
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl; return 0;
}