がんxgzcの問題に数論シリーズソリューション

干し草振り子
  イタリアその:、nは1が配置されているQの列挙を有するが、各セクションは、Lの最小値を与える〜R aは、Q矛盾文の最初の前の数。
  \(1 \当量のn \の当量
10 ^ 6、Q \当量25000 \)   溶液:バイナリ答え。交差点の大部分は、特定の小範囲を含み、特定のセットが矛盾している場合。
  関係が互いに素セットまたはセグメントツリーを含むことができ(ディスジョイントセット真がんああ)
  セグメントツリーの小さな話。互いに素なセット場合は、[L、R]は、親ノード間隔R + 1に向かう力によって覆われています。検索(l)は> rの場合には、間隔が覆われていることを証明します。(グッド形而上学ああ) (xgzcから均等に立証少し複雑さを共有することができます)
  複雑さ:\(O(Q \ Qが* \アルファ(N-)をログ)\)

#include<bits/stdc++.h>
using namespace std;
#define maxn 25005
struct Query
{
    int l,r,v;
    inline friend bool operator < (Query a,Query b)
        {
            return a.v>b.v;
        }
}query[maxn],tmp[maxn];
int fa[1000005],n;
inline int findf(int x)
{
    return (fa[x]==x)?x:(fa[x]=findf(fa[x]));
}
bool check(int x)
{
    for(int i=1;i<=x;++i) tmp[i]=query[i];
    for(int i=1;i<=n+1;++i) fa[i]=i;
    sort(tmp+1,tmp+x+1);
    int l1,l2,r1,r2;
    l1=l2=tmp[1].l,r1=r2=tmp[1].r;
    for(int i=2;i<=x;++i)
    {
        if(tmp[i].v<tmp[i-1].v)
        {
            if(findf(l1)>r1) return false;
            for(int j=fa[l2];j<=r2;j=fa[j])
            {
                findf(j);
                fa[j]=findf(j+1);
            }
            l1=l2=tmp[i].l,r1=r2=tmp[i].r;
        }
        else
        {
            l1=max(l1,tmp[i].l),l2=min(l2,tmp[i].l);
            r1=min(r1,tmp[i].r),r2=max(r2,tmp[i].r);
            if(r1<l1) return false;
        }
    }
    if(findf(l1)>r1) return false;
    return true;
}
int main()
{
    freopen("bales.in","r",stdin),freopen("bales.out","w",stdout);
    int q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=q;++i)
        scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].v);
    int l=1,r=q+1,mid;
    while(l<r)
    {
        mid=(l+r)>>1;
        if(check(mid)) l=mid+1;
        else r=mid;
    }
    printf("%d\n",l>q?0:l);
    return 0;
}

  Bサーベルの
  タイトルの意味:指定された\(N * m個\)トレリス線図、(。Y = Xの+ 1 \)\左上の点は、Q(0、から、上方向にだけまたは右に(オンライン)すべてを行っていません0)19999999パス部アナログする(n、m)はデジタルです。\(2 \当量のm \当量の
n個の\当量10 ^ {10} \)   対処:プログラム番号不正とみなさ。明らかに、すべてのそのような経路は、線とすることができる\(Y = X \ + 2 ) 右下から倍の左上に外側の経路に沿って、すなわちから(0,0)、(M-2、N + 2 ) スキーム番号。そう\(ANS = C_ {N +
M} ^ {M} -C_ {N + M} ^ {M-2} \)   ルーカスに小さい弾性率に起因します。
  複雑さ:\(O(MOD)\)

#include<bits/stdc++.h>
using namespace std;
#define mod 19999999
#define ll long long
ll inv[mod+5],fac[mod+5];
inline void exgcd(ll a,ll b,ll& x,ll& y)
{
    if(!b)
    {
        x=1,y=0;
        return;
    }
    exgcd(b,a%b,y,x);
    y-=a/b*x;
}
inline void pre(int x)
{
    inv[0]=fac[0]=1;
    for(int i=1;i<=x;++i)
        fac[i]=fac[i-1]*i%mod;
    ll tx,ty;
    exgcd(fac[x],mod,tx,ty);
    inv[x]=(tx%mod+mod)%mod;
    for(int i=x-1;i;--i)
        inv[i]=(i+1)*inv[i+1]%mod;
}
inline ll c(ll x,ll y)
{
    return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
inline ll lucas(ll x,ll y)
{
    return c(x%mod,y%mod)*c(x/mod,y/mod)%mod;
}
int main()
{
    freopen("saber.in","r",stdin),freopen("saber.out","w",stdout);
    int n,m;
    scanf("%d%d",&n,&m);
    pre((n+m+2)%mod);
    printf("%lld\n",(lucas(n+m,m)-lucas(n+m,m-2)+mod)%mod);
    return 0;
}

  Cは十分ではなかった
  というイタリア:質問への長いブラシ。彼はそれを行うことはありません。
  与えられたN、検索
  \ [\ sum_ {i = 1 } ^ {N} \ sum_ {J = 1} ^ {N} \ sum_ {k = 1} ^ {n}が{[J \ミッドI] [(jは+ K)\ミッドI]}
MOD 998244353 \ \]   前記\([X]は\) xは1または0である場合、この値が真で表します。\(N当量10 7 \ \
^)を   溶液:明らかに\(ANS = \ sum_ {I = 1} ^ {n}は{\ FRAC {D(I)^ 2-D(I)} {2}} \) 、ここで、dは、多数の要因の関数です。
  リニア画面をすることができます。
  複雑さ:\(O(N)\)

#include<bits/stdc++.h>
using namespace std;
#define mod 998244353
#define maxn 10000005
int n,vis[maxn],id[maxn],num[maxn],prime[1000005],cnt;
inline void eular(int x)
{
    int tmp;
    for(int i=2;i<=x;++i)
    {
        if(!vis[i]) prime[++cnt]=i,id[i]=2,num[i]=1;
        for(int j=1;j<=cnt&&i*prime[j]<=x;++j)
        {
            tmp=i*prime[j];
            vis[tmp]=1;
            if(i%prime[j])
            {
                id[tmp]=2*id[i];
                num[tmp]=1;
            }
            else
            {
                id[tmp]=id[i]*(num[i]+2)/(num[i]+1);
                num[tmp]=num[i]+1;
                break;
            }
        }
    }
}
int main()
{
    freopen("good.in","r",stdin),freopen("good.out","w",stdout);
    scanf("%d",&n);
    eular(n+2);
    long long ans=0;
    int tmp;
    for(int i=1;i<=n;++i)
    {
        tmp=id[i];
        ans+=((tmp*tmp-tmp)>>1)%mod;
        ans%=mod;
    }
    printf("%lld\n",ans);
    return 0;
}

  Dは、大きな財産をこもっ
  ロングとhyjゲームの問題を行います。イタリアであること。N-1-質問数2〜nがあります。各質問には、一人だけ(またはやっていないもの)によって行うことができます。どんな質問をしてから長いとhyj需要は二つの数は、プログラムの数にプライムではありません選択しました。二人は、質問することはできません。モジュロpのプログラム番号。\(N \の当量500、p個の
\の当量10 ^ 9 \)   溶液:圧力状\(\ SQRT N \)セット内の素数。セット\(DP [I] [jが 】\) Iの素因数のセットから選択された竜の数を表し、hyjは、グループJから選択されます。このように、大きな素数を残される(かもしれません)。セット\(F1 [I] [J ] [K]、F2 [I] [J] [K] \) を表し、i番目のプログラムの二組、から選択された候補者のJ、K、大きな素数の数があります。
  二つの配列の初期値DP。
  転送\(F1 [I]、[J \ S MID] [K] + = F1 [I] [J] [K](S \&K == 0)\)別の共感。
  \(ANS = \ sum_ {I
= 0} \ sum_ {J = 0} {DP [I] [J]} \)   私はそれ以外の場合は、ロールアウトするMLEしたい注意。
  複雑:\(O(N-2 * 2 ^ ^ * 8 8)\) 以降の比(\ \ SQRT N \)より小さい第素数19、8)

#include<bits/stdc++.h>
using namespace std;
struct Num
{
    int s,num;
    inline friend bool operator < (Num a,Num b)
        {
            if(a.num==b.num) return a.s<b.s;
            return a.num<b.num;
        }
}num[505];
int prime[9]={0,2,3,5,7,11,13,17,19};
int n,p,dp[257][257],tmp[2][257][257],ans;
inline void add(int& a,const int& b)
{
    a=(a+b)%p;
}
int main()
{
    freopen("rich.in","r",stdin),freopen("rich.out","w",stdout);
    scanf("%d%d",&n,&p);
    int tn;
    for(int i=2;i<=n;++i)
    {
        tn=i;
        for(int j=1;j<=8;++j)
        {
            if(tn%prime[j]) continue;
            num[i].s|=(1<<(j-1));
            while(!(tn%prime[j])) tn/=prime[j];
        }
        num[i].num=tn;
    }
    sort(num+2,num+n+1);
    dp[0][0]=1;
    for(int i=2;i<=n;++i)
    {
        if(i==2||num[i].num==1||num[i].num xor num[i-1].num)
            memcpy(tmp[1],dp,sizeof(dp)),memcpy(tmp[0],dp,sizeof(dp));
        for(int j=255;j>=0;--j)
            for(int k=255;k>=0;--k)
            {
                if(!(k&num[i].s)) add(tmp[0][j|num[i].s][k],tmp[0][j][k]);
                if(!(j&num[i].s)) add(tmp[1][j][k|num[i].s],tmp[1][j][k]);
            }
        if(i==n||num[i].num==1||num[i].num xor num[i+1].num)
            for(int j=0;j<=255;++j)
                for(int k=0;k<=255;++k)
                    dp[j][k]=((tmp[0][j][k]+tmp[1][j][k]-dp[j][k])%p+p)%p;
    }
    for(int i=255;i>=0;--i)
        for(int j=255;j>=0;--j)
            if(!(i&j)) add(ans,dp[i][j]);
    printf("%d\n",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/123789456ye/p/11521400.html