[12.12]日記

12.12日記

CF

  1. 1234D:https://codeforces.com/problemset/problem/1234/D

実際には、直接ビルドそれぞれの文字のための木のような配列には、26を構築することができます。必ず手紙、答え+1を示し、ゼロでない場合は、間隔を尋ねると。時間複雑\(O(26N \ nはログ )\)

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+20;
int c[27][M],n;
char s[M];
inline int lowbit(int x){return x&(-x);}
inline void operate(int pos,int k){
    for (int i=pos;i<=n;i+=lowbit(i))
        c[s[pos]-'a'][i]+=k;
}
inline int query(int ch,int x){//1-x的和
    int ans=0;
    for(int j=x;j;j-=lowbit(j))
        ans+=c[ch][j];
    return ans;
}
inline int BITquery(int l,int r){
    int ans=0;
    for(int i=0;i<=25;++i)
        ans+=(query(i,r)!=query(i,l-1));
    return ans;
}
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=1;i<=n;++i)
        operate(i,1);
    int q;
    scanf("%d",&q);
    for(int i=1;i<=q;++i){
        int op;
        scanf("%d",&op);
        if (op==1){
            int pos;
            char sc[2];
            scanf("%d%s",&pos,sc);
            operate(pos,-1);
            s[pos]=sc[0];
            operate(pos,1);
        }
        else{
            int l,r;
            scanf("%d%d",&l,&r);
            printf("%d\n",BITquery(l,r));
        }
    }
    return 0;
}
  1. 1185C2:https://codeforces.com/problemset/problem/1185/C2

この質問は、に変換することができる:1-iの範囲内で、多くのピック数、確保しつつとして<馬[I + 1]。そして、小さな多数の選択する必要がある、と考えるのは簡単です。しかし、個々の数字の数の間隔が共通のデータ構造で、変更されるたびに維持することは容易ではないので、暴力的と考えられます。

直接TOT配列は、回数は現在、各番号は、ストレージを表示されています。小から大に毎回統計や暴力だから、値の最大数を選び出し、その後、切断された答えを得ることができます見つけます。

時間複雑\(O(100N)\)

ある\(O(N \ログ^ 2N)\) のアプローチは、最初にソートし、データの元の順序が配列のソートに対応する位置に、ツリーを確立する、読み取るプレス機を読み取るようにされています次に、メンテナンス(数および間隔の数、2ツリーアレイに対応する)期間と、呼び掛けゾーン後の2点(1-X)、Xの最も右、および間隔を満たす<馬[I + 1]を見つけます。これもすることができます。テスト時間が比較的大きい場合には、我々はこのアイデアを使用することができ、また、スーパートラブルを書くこと。

#include<bits/stdc++.h>
using namespace std;
const int M=2e5+20;
int tot[105];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        int c;
        scanf("%d",&c);
        int T=m-c,p=1;
        while(p<=100&&T>=tot[p]*p)
            T-=tot[p]*p,++p;
        int ans=0;
        for(int j=1;j<=p-1;++j)
            ans+=tot[j];
        ans+=T/p;
        printf("%d",max(i-ans-1,0));
        if(i!=n)
            putchar(' ');
        ++tot[c];
    }
    putchar('\n');
    return 0;
}
  1. 1163B2:https://codeforces.com/problemset/problem/1163/B2

セクション1-iに必要な数の後、削除を満たすには、すべて同じ回数を示します。私の最大値を検索します。

アイデアは:発生回数は、私が持っているものの数で格納するセットを、S [i]を開く1E5。各アレイ店舗のオープン時間(すなわち、対応するセット)発生数に加えて。MXのオカレンスの最大数を再記録し、その後、条件が2つだけのケースを満足しています。

  • MX = 1、全ての数はその後、ちょうど行を削除して、確かに満足し、一度表示されます。
  • MXのみ出現数で、数字の残りの部分は、MX-1回登場しています。これにより、合計数を決定するために使用することができます。それを削除することをこの場合、MX回。

そして、この問題は数秒でしょう。複雑\(O(N \ N-ログ)\)

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+20;
unordered_set<int> s[M];
int cnt[M];
int main(){
    int n,ans=0,mx=0;
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        int c;
        scanf("%d",&c);
        s[cnt[c]].erase(c);
        ++cnt[c];
        s[cnt[c]].insert(c);
        if (mx<cnt[c])
            mx=cnt[c];
        if ((s[mx].size()==1&&s[mx].size()*mx+s[mx-1].size()*(mx-1)==i)||(s[mx].size()*mx==i-1)||(mx==1))
            ans=i;
    }
    printf("%d\n",ans);
    return 0;
}

明日の計画

  1. ツリー径、重心、チェーンスプリットツリー
  2. CDQ

おすすめ

転載: www.cnblogs.com/diorvh/p/12032658.html