A. Favorite Sequence
模拟题
代码
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int a[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
int n;
cin >> n;
fir(i,1,n) cin >> a[i];
int i = 1,j = n;
while(i <= j){
if(i == j) cout << a[i++] << ' ';
else cout << a[i++] << " " << a[j--] << " ";
}
cout << "\n";
}
return 0;
}
B. Last Year’s Substring
就枚举头尾有没有:
2020xxx
2xxx020
20xxx20
202xxx0
xxx2020
就ok了
代码:
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
string str = "2020";
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
int n;
cin >> n;
string s;
cin >> s;
s = ' ' + s;
bool f = 0;
fir(k,0,4){
bool ff = 1;
fir(i,1 ,k){
if(s[i] != str[i-1]){
ff = 0;
break;
}
}
int kk = 4-k;
fir(i,0,kk-1){
if(str[3-i] != s[n-i]){
ff = 0;
break;
}
}
if(ff){
f = 1;
break;
}
}
if(f) cout << "YES\n";
else cout << "NO\n";
}
return 0;
}
C. Unique Number
dfs瞎搞或者直接打表就好了(找不到当时打表的代码了)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int ans[50] = {1
,2
,3
,4
,5
,6
,7
,8
,9
,19
,29
,39
,49
,59
,69
,79
,89
,189
,289
,389
,489
,589
,689
,789
,1789
,2789
,3789
,4789
,5789
,6789
,16789
,26789
,36789
,46789
,56789
,156789
,256789
,356789
,456789
,1456789
,2456789
,3456789
,13456789
,23456789
,123456789
,-1
,-1
,-1
,-1
,-1};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cout << ans[n-1] << "\n";
}
return 0;
}
D. Add to Neighbour and Remove
枚举一下最后数组的长度,如果数组的和sum%len==0,那么这个len就有机会成为答案.具体做法就是得到平均值avg=sum/len后遍历数组如果avg>a[i]就不可以,如果是a[i]<avg就贪心的直接累加到右边,因为它一定要增大,这个时候增大的幅度是最小的.
代码
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int a[N],b[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
int n,sum=0;
cin >> n;
fir(i,1,n) cin >> b[i],sum+=b[i];
int f = -1;
afir(len,n,1){
int avg = sum%len;
if(avg) continue;
avg = sum/len;
bool ff = 1;
fir(i,1,n) a[i] =b[i];
fir(i,1,n){
if(a[i] > avg){
ff = 0;
break;
}
if(a[i] < avg){
if(i!=n) a[i+1] += a[i];
else{
ff = 0;
break;
}
}
}
if(ff){
f = n-len;
break;
}
}
cout << f << '\n';
}
return 0;
}
E1. Close Tuples (easy version)
E2. Close Tuples (hard version)
直接考虑E2.翻译一下题目:从大小为n的数组中选出m个元素,问能选出多少个序列中max-min<=k的有序对.
可以直接排序,然后二分出最后一个小于等于a[i]-k的位置pos,然后用组合数学的知识可以知道选i的方案数是C(i-pos,m-1).累加起来即可
代码:
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const LL mo=1e9+7;
LL C(LL n,LL m){
static LL M=0,inv[N],mul[N],invMul[N];
while(M<=n){
if(M){
inv[M]=M==1?1:(mo-mo/M)*inv[mo%M]%mo;
mul[M]=mul[M-1]*M%mo;
invMul[M]=invMul[M-1]*inv[M]%mo;
}
else mul[M]=1,invMul[M]=1;
M++;
}
return mul[n]*invMul[m]%mo*invMul[n-m]%mo;
}
int a[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
int n,m,k;
cin >> n >> m >> k;
fir(i,1,n) cin >> a[i];
sort(a+1,a+1+n);
LL ans = 0;
afir(i,n,1){
int p = upper_bound(a+1,a+1+n,a[i]-k-1) - a;
int num = i-p;
if(num < m-1) continue;
ans = (ans + C(num,m-1))%mo;
}
cout << ans << "\n";
}
return 0;
}
F. The Treasure of The Segments
这题细节比较麻烦.思路应该不难.
把题目转换一下,删掉最少区间的意思就是找到每个区间最多和多少个区间相交num[i],答案就是max(n-num[i]).
考虑按区间的右边界排序,然后顺序循环找到当前区间i左边界前面有多少个前面区间的右边界.然后再逆序循环看区间i后面有多少个区间的左边界打到[ l[i],r[i] ]上,这个过程可以用树状数组维护一下.
注意一下排序的时候右边界相同的时候左边界大的要在前面,可以画图理解一下.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
vi all;
int getpos(int x){
return lower_bound(ALL(all),x) - all.begin();
}
pii p[N];
int c[N],n,num[N],tn;
void add(int p,int v){
for(;p<=tn;p+=p&-p) c[p] += v;
}
int ask(int p){
int res = 0;
for(;p;p-=p&-p) res += c[p];
return res;
}
bool cmp(pii a,pii b){
return a.ft==b.ft?a.sd>b.sd:a.ft<b.ft;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
all.clear();
all.pb(INT_MIN);
cin >> n;
fir(i,1,n) cin >> p[i].sd >> p[i].ft,all.pb(p[i].ft),all.pb(p[i].sd),all.pb(p[i].ft+1),all.pb(p[i].sd+1);
sort(p+1,p+1+n,cmp);
sort(ALL(all));
all.erase(unique(ALL(all)),all.end());
tn = all.size()-1;
fir(i,1,n){
int pos = lower_bound(p+1,p+1+n,mpr(p[i].sd,0))-p;
pos--;
num[i] += i-pos;
}
afir(i,n,1){
p[i].ft = getpos(p[i].ft);
p[i].sd = getpos(p[i].sd);
num[i] += ask(p[i].ft)-ask(p[i].sd-1);
add(p[i].sd,1);
}
int ans = INT_MAX;
fir(i,1,n) ans = min(ans,n-num[i]);
cout << ans << "\n";
fir(i,1,n) add(p[i].sd,-1),num[i] = 0;
}
return 0;
}