Codeforces Round 889 (Div. 2)
Codeforces Round 889 (Div. 2)
A - Dalton the Teacher
思路:找出pi=i的数量,除2为答案

#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ int n;cin>>n; int ans=0; for(int i=1,x;i<=n;++i){ cin>>x; if(x==i)ans++; } cout<<(ans+1)/2<<'\n'; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); cin>>t; while(t--){ solve(); } return 0; }
B - Longest Divisors Interval
思路:当n不为2的倍数,最多分解为1个数(1 2 3 4 5 6...);
当n不为3的倍数,最多分解为2个数(1 2 3 4 5 6 7 8 9);
......
从小枚举不整除n的最小倍数,答案即为最小倍数-1

#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ int n;cin>>n; if(n%2){ cout<<1<<'\n';return ; } for(int i=1;i<=n;++i){ if(n%i){ cout<<i-1<<'\n';return; } } cout<<n<<'\n'; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); cin>>t; while(t--){ solve(); } return 0; }
C1 - Dual (Easy Version)
思路:操作次数最多50次;
当全为非负数时,从左加到右即可(操作为{ i,i -1 }),需要n-1次
当全为非正数时,从右加到左即可(操作为{ i,i+1 }),需要n-1次
当有正有负时,将一个正数p自加5次(最后会大于20),第2个数加两次p,而后依次往后加(操作为{ i,i-1 }),每次加两次,那么最多为5+2*(n-1)次

#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } int T=1; void solve(){ int n;cin>>n; vector<int>ve(n); int mp,ma=-25; for(int i=0;i<n;++i){ cin>>ve[i]; if(ve[i]>ma){ ma=ve[i],mp=i+1; } } if(n==1){ cout<<0<<'\n';return ; } if(ma<=0){ cout<<n-1<<'\n'; for(int i=n;i>1;--i)cout<<i-1<<' '<<i<<'\n'; }else{ cout<<2*n+3<<'\n'; for(int i=1;i<=5;++i)cout<<mp<<' '<<mp<<'\n'; cout<<2<<' '<<mp<<'\n'; cout<<2<<' '<<mp<<'\n'; for(int i=3;i<=n;++i){ cout<<i<<' '<<i-1<<'\n'; cout<<i<<' '<<i-1<<'\n'; } } return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); //int T=1; init(); cin>>T; while(T--){ solve(); } return 0; }
C2 - Dual (Hard Version)
思路:操作次数最多31次;
a.考虑将序列全转为非负数或非正数之后,需要n-1次,即最多要19次
对于序列含有非负和非正的情况:
若abs(max正)>=abs(max负):
1.cnt负<=12,将所有负数加上max正,即所有数都为非负数,进行a操作(最多需要12+n-1次)
2.cnt负>12,cnt正<8,对一个负数p自加5次(一定小于20),所有正数加上p,即所有数都为非正数,进行a操作(最多需要5+7+n-1次)
当abs(max负)>abs(max正)时同理。

#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ int n;cin>>n; vector<int>ve(n+1); int ma=-25,mi=25,maa,mii,cntf=0,cntz=0; for(int i=1;i<=n;++i){ cin>>ve[i]; if(ve[i]<0)cntf++; else if(ve[i]>0)cntz++; if(ve[i]>ma)ma=ve[i],maa=i; if(ve[i]<mi)mi=ve[i],mii=i; } if(ma<0){ cout<<n-1<<'\n'; for(int i=n;i>1;--i)cout<<i-1<<' '<<i<<'\n'; }else if(mi>0){ cout<<n-1<<'\n'; for(int i=1;i<n;++i)cout<<i+1<<' '<<i<<'\n'; }else if(ma==mi&&ma==0){ cout<<0<<'\n'; }else if(abs(ma)>=abs(mi)){ if(cntf<=12){ cout<<cntf+n-1<<'\n'; for(int i=1;i<=n;++i) if(ve[i]<0)cout<<i<<' '<<maa<<'\n'; for(int i=1;i<n;++i)cout<<i+1<<' '<<i<<'\n'; }else{ cout<<5+cntz+n-1<<'\n'; for(int i=1;i<=5;++i)cout<<mii<<' '<<mii<<'\n'; for(int i=1;i<=n;++i) if(ve[i]>0)cout<<i<<' '<<mii<<'\n'; for(int i=n;i>1;--i)cout<<i-1<<' '<<i<<'\n'; } }else{ if(cntz<=12){ cout<<cntz+n-1<<'\n'; for(int i=1;i<=n;++i) if(ve[i]>0)cout<<i<<' '<<mii<<'\n'; for(int i=n;i>1;--i)cout<<i-1<<' '<<i<<'\n'; }else{ cout<<5+cntf+n-1<<'\n'; for(int i=1;i<=5;++i)cout<<maa<<' '<<maa<<'\n'; for(int i=1;i<=n;++i) if(ve[i]<0)cout<<i<<' '<<maa<<'\n'; for(int i=1;i<n;++i)cout<<i+1<<' '<<i<<'\n'; } } return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); cin>>t; while(t--){ solve(); } return 0; }
D - Earn or Unlock
思路:有两个操作:往后开v个锁牌、获取当前牌的v后丢弃;
若对第i个牌进行操作1,需要开vi个锁牌,相当于将最后一张已开锁的牌的后vi个牌打开;
这里可以用二进制来表示,1表示开锁,0表示锁或丢弃;每次操作一相当于将当前状态右移vi位
若对第i个牌进行操作2,得到sum[i]-i,(sum表示前缀和),获取后将i丢弃

#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ int n;cin>>n; vector<int>ve(N); for(int i=0;i<n;++i)cin>>ve[i]; bitset<N>f; int ans=0,s=0; f[0]=1; n<<=1; for(int i=0;i<n;++i){ f|=(f<<ve[i]); s+=ve[i]; if(f[i]==1){ ans=max(ans,s-i); f[i]=0; } } cout<<ans; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); //cin>>t; while(t--){ solve(); } return 0; }