暑假集训csp提高模拟9
赛时rank15 T1 0,T2 100,T3 0,T4 0
T1,T3 都会做,然后都挂了。
恼了,挂200,不愧是我,唐
T1 大众点评
简单的交互。
考虑选择相邻的两组,小的单独存一个,大的单独存一个,是比较200次
再将大的互相比较,小的互相比较,各200次
点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
#include "ramen.h"
using namespace std;
void Ramen(int N){
vector<int> mn,mx;
// Answer(1000000,10000);
if(N == 1)return Answer(0,0),void();
int mxpos,mnpos;
for(int i = 1;i < N; i += 2){
int res = Compare(i-1,i);
if(res == -1){
mn.push_back(i-1);
mx.push_back(i);
}
else{
mx.push_back(i-1);
mn.push_back(i);
}
}
if(N&1) mn.push_back(N-1),mx.push_back(N-1);
mxpos = mx[0];
for(int i = 1;i < mx.size(); ++i){
if(Compare(mx[i],mxpos) == 1) mxpos = mx[i];
}
mnpos = mn[0];
for(int i = 1;i < mn.size(); ++i){
if(Compare(mn[i],mnpos) == -1) mnpos = mn[i];
}
Answer(mnpos,mxpos);
}
T2 录取查询
[ABC285F] Substring of Sorted String
简单题。
我们发现当一个字符串可以是子串时当且仅当它是升序排列的,且除了第一个字符和最后一个字符,中间的字符在整个字符串的其他位置没有出现过。
权值树状数组记录一下出现次数,线段树记录一下区间极值、区间是否单调。注意一下树状数组和线段树的细节。
点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;using db = double;
#ifdef LOCAL
FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
// FILE *ErrFile=errfile("err.err");
#else
FILE *Infile = stdin,*OutFile = stdout;
//FILE *ErrFile = stderr;
#endif
const int N = 1e5 + 10;
struct BIT{
private:
#define lowbit(x) (x&(-x))
int tree[N];
public:
int mx;
inline void update(int pos,int val){
for(int i = pos;i <= mx;i += lowbit(i)) tree[i] += val;
}
inline int query(int pos){
int res = 0;
for(int i = pos; i;i -= lowbit(i)) res += tree[i];
return res;
}
}T[27];
char s[N];
int n,m;
class Segment_Tree{
private:
struct segment_tree{
int l,r;bool pd;
char mn,mx;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define pd(x) tree[x].pd
#define mn(x) tree[x].mn
#define mx(x) tree[x].mx
}tree[N<<2];
public:
inline void pushup(int k){
pd(k) = ((s[r(k<<1)] <= s[l(k<<1|1)]) && pd(k<<1) && pd(k<<1|1));
mn(k) = min(mn(k<<1),mn(k<<1|1));
mx(k) = max(mx(k<<1),mx(k<<1|1));
}
void build(int k,int l,int r){
l(k) = l,r(k) = r;
if(l == r) return pd(k) = true,mn(k) = mx(k) = s[l],void();
int mid = (l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
// cerr<<l(k)<<' '<<r(k)<<' '<<r(k<<1)<<' ' <<s[r(k<<1)]<<' '<<l(k<<1|1)<<' '<<s[l(k<<1|1)]<<'\n';
}
void update(int k,int pos){
if(l(k) == r(k)) return mn(k) = mx(k) = s[pos],void();
int mid = (l(k) + r(k))>>1;
if(pos <= mid) update(k<<1,pos);
else update(k<<1|1,pos);
pushup(k);
}
bool query(int k,int l,int r){
if(l <= l(k) && r(k) <= r) return pd(k);
int mid = (l(k) + r(k)) >> 1;
if(l > mid) return query(k<<1|1,l,r);
if(r <= mid) return query(k<<1,l,r);
return query(k<<1,l,r) && query(k<<1|1,l,r) && (s[r(k<<1)] <= s[l(k<<1|1)]);
}
char query_min(int k,int l,int r){
if(l <= l(k) && r(k) <= r) return mn(k);
int mid = (l(k) + r(k)) >> 1;
if(r <= mid) return query_min(k<<1,l,r);
if(l > mid) return query_min(k<<1|1,l,r);
return min(query_min(k<<1,l,r),query_min(k<<1|1,l,r));
}
char query_max(int k,int l,int r){
if(l <= l(k) && r(k) <= r) return mx(k);
int mid = (l(k) + r(k)) >> 1;
if(r <= mid) return query_max(k<<1,l,r);
if(l > mid) return query_max(k<<1|1,l,r);
return max(query_max(k<<1,l,r),query_max(k<<1|1,l,r));
}
}St;
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
cin>>n>>(s+1);
for(int i = 0;i <= 26; ++i) T[i].mx = n;
for(int i = 1;i <= n; ++i) T[s[i]-'a'].update(i,1);
St.build(1,1,n);
cin>>m;
while(m--){
int op,l,r,x;
char c;
cin>>op;
if(op == 1){
cin>>x>>c;
T[s[x]-'a'].update(x,-1);
s[x] = c;
T[s[x]-'a'].update(x,1);
St.update(1,x);
}
else{
cin>>l>>r;
if(!St.query(1,l,r)) cout<<"No\n";
else{
bool flag = true;
int bg = St.query_min(1,l,r)-'a';
int ed = St.query_max(1,l,r)-'a';
for(int i = bg;i <= ed; ++i){
if(i == s[l]-'a' || i == s[r] -'a') continue;
if(l > 1?T[i].query(r) - T[i].query(l-1) != T[i].query(n):T[i].query(r) != T[i].query(n)){
cout<<"No\n";
flag = false;
break;
}
}
if(flag) cout<<"Yes\n";
}
}
}
}
T3 精准打击
从根节点考虑,若任意一棵子树都大于x,那么就将根节点的所有连边剪断,递归至任意子树。
如果任意一颗子树不大于x,那么就保留根节点,看看要保留几颗子树。如果有不满一颗的,递归处理。
注意根节点上是否要剪边。
就,没了
点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;using db = double;
#ifdef LOCAL
FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
// FILE *ErrFile=errfile("err.err");
#else
FILE *Infile = stdin,*OutFile = stdout;
//FILE *ErrFile = stderr;
#endif
ll d,k,x;
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
int T;
cin>>T;
while(T--){
cin>>d>>k>>x;
ll res = k;
ll a[100];
a[0] = 1;
for(int i = 1;i <= d; ++i) a[i] = a[i-1] * k + 1;
ll ans = 1e18;
for(int i = 0;i <= d; ++i){
if(a[i] >= x){
ll res = !(i == d);
ll tot = a[i] - x,j = i - 1;
while(tot && j >= 0){
res += tot/a[j];
tot %= a[j];
j--;
}
ans = min(ans,res);
}
}
cout<<ans<<'\n';
}
}
T4 你画我猜
两个神仙玩游戏,Alice不知道,Bob也不知道,几个不知道后,就都知道了。
太难了。跳了。
__________________________________________________________________________________________
本文来自博客园,作者:CuFeO4,转载请注明原文链接:https://www.cnblogs.com/hzoi-Cu/p/18327019