暑假集训csp提高模拟16

赛时 rank 38,T1 20,T2 50,T3 0,T4 0

T2 挂分原因 : 莫队n,m写反了,但样例中这俩一样,遂寄

T1 九次九日九重色

\[\color{Green}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

\[\color{Red}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

\[\color{Blue}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

\[\color{Yellow}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

\[\color{Pink}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

\[\color{Orange}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

\[\color{Purple}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

\[\color{#66CCFF}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

\[\color{Brown}{\Huge{!!!!!!!!!九日\,!!!!!!!!!}} \]

不用数了正好九个

玩galgame有啥意思不如玩我们nine suns

调和级数预处理出每个数的倍数,时间复杂度\(O(n\log n)\)

然后就是求一个在二维平面上的最长上升子序列

点此查看代码
#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)
#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
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 2e5 + 10;
int n,a[N],b[N],sum[N];
vector<int> can[N];
inline void pre_work(){
    for(int i = 1;i <= n; ++i){
        for(int j = i;j <= n;j += i){
            can[i].push_back(j);
        }
    }
}
int ans = 0;
class BIT{
private:
    int tree[N];
    #define lowbit(x) (x&(-x))
public:
    int mx = 0;
    inline void update(int pos,int val){
        for(int i = pos;i <= mx;i += lowbit(i)) tree[i] = max(val,tree[i]);
    }
    inline int query(int pos){
        int res = 0;
        for(int i = pos; i;i -= lowbit(i)) res = max(tree[i],res);
        return res;
    }
}T;
int posa[N],posb[N];
inline void solve(){
    cin>>n;
    for(int i = 1;i <= n; ++i) cin>>a[i],posa[a[i]] = i;
    for(int i = 1;i <= n; ++i) cin>>b[i],posb[b[i]] = i;
    pre_work();T.mx = n;
    for(int i = 1;i <= n; ++i){
        vector<pair<int,int> > p;
        for(auto j : can[a[i]]){
            p.push_back(make_pair(posb[j],T.query(posb[j]-1)+1));
        }
        for(auto j : p) T.update(j.first,j.second);
    }
    for(int i = 1;i <= n; ++i) ans = max(ans,T.query(i));
    cout<<ans;
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

T2 天色天歌天籁音

大爷的字符串题

是道莫队水题

先离散化

记录一下一个数出现的次数和所有数出现次数的出现次数即可

可能有点离谱。

就随便拿个样例说一下

1 2 3 4 4 5 6

如上,我们要求\(l = 2,r = 6\)

那么\(cnt_1 = 0,cnt_2 = 1,cnt_3 = 1,cnt_4 = 2,cnt_5 = 1,cnt_6 = 1\)

还有\(tot_0 = 1,tot_1 = 4,tot_2 = 1,tot_3 = tot_4 = tot_5 = tot_6 = 0\)

如果从\(l=2,r=6\)转移到\(l=2,r=3\)

当右指针从5移动到4时,那么就有\(cnt_4=1\),那么\(tot_2=1\)

我们发现,每次转移,答案至多会更改1

若最大的出现次数减没,则最优答案就是最大次数减一,若有更大的,更新。

点此查看代码
#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)
#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
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 2e5 + 10;
int n,m,a[N],pos[N],L[N],R[N],len,ans[N];
vector<int> num;
struct Query{int id,l,r;}q[N];
int cnt[N],tot[N];
inline void solve(){
    cin>>n>>m;
    for(int i = 1;i <= n; ++i) cin>>a[i],num.emplace_back(a[i]);
    sort(num.begin(),num.end());
    num.erase(unique(num.begin(),num.end()),num.end());
    for(int i = 1;i <= n; ++i)
        a[i] = lower_bound(num.begin(),num.end(),a[i])-num.begin()+1;
    len = sqrt(n);
    for(int i = 1;i <= len; ++i) L[i] = R[i - 1] + 1,R[i] = i * len;
    if(R[len] < n) R[len] = n;
    for(int i = 1;i <= len; ++i) for(int j = L[i];j <= R[i]; ++j) pos[j] = i;
    for(int i = 1;i <= m; ++i) cin>>q[i].l>>q[i].r,q[i].id = i;
    sort(q+1,q+1+m,[](Query x,Query y){return pos[x.l] == pos[y.l]?(pos[x.l]&1?x.r>y.r:x.r<y.r):x.l<y.l;});
    int left = 1,right = 0,res = 0;
    tot[0] = num.size();
    for(int i = 1;i <= m; ++i){
        int l = q[i].l,r = q[i].r;
        while(left < l){
            if(cnt[a[left]] >= 0) tot[cnt[a[left]]]--;
            if(cnt[a[left]] > 0) tot[cnt[a[left]]-1]++;
            if(res == cnt[a[left]] && !tot[cnt[a[left]]]) res--;
            cnt[a[left]]--;
            left++;
        }
        while(right < r){
            right++;
            if(cnt[a[right]] >= 0) tot[cnt[a[right]]]--;
            cnt[a[right]]++;
            if(cnt[a[right]] >= 0) tot[cnt[a[right]]]++;
            res = max(res,cnt[a[right]]);
        }
        while(left > l){
            left--;
            if(cnt[a[left]]) tot[cnt[a[left]]]--;
            cnt[a[left]]++;
            tot[cnt[a[left]]]++;
            res = max(res,cnt[a[left]]);
        }
        while(right > r){
            if(cnt[a[right]]) tot[cnt[a[right]]]--;
            if(cnt[a[right]] > 0) tot[cnt[a[right]]-1]++;
            if(res == cnt[a[right]] && !tot[cnt[a[right]]]) res--;
            cnt[a[right]]--;
            right--;
        }
        ans[q[i].id] = res;
    }
    for(int i = 1;i <= m; ++i) cout<<-ans[i]<<'\n';
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

T3 春色春恋春熙风

Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

Dsu On Tree

今天学这个,T4不改了

T4 雪色雪花雪余痕

posted @ 2024-08-08 15:41  CuFeO4  阅读(32)  评论(0编辑  收藏  举报