[CometOJ] CometOJ#8問題解決レポート

競争を入力するにはここをクリック

\(\) キラークイーン(問題の表面を見るにはここをクリックしてください

大雑把な質問の意味:辞書順最小の文字列を見つけます。

サブテーマを送信するためにゲームが常にあります。

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
using namespace std;
int n;string s;
int main()
{
    RI i;string st;for(cin>>n>>s,i=2;i<=n;++i) cin>>st,st<s&&(s=st,0);//读入,求字典序最小字符串
    return cout<<s<<endl,0;//输出
}

\(B \) サポートシティ(問題の表面を見るにはここをクリックしてください

一般的な問題の意味:それぞれについて\(X \) シーク(\ \ sum_ 1} ^ {N-I =(a_iを-A_X)2 ^ \。)

正方形の解体:

\ [\ Sum_ {i = 1} ^ N(a_iを '2-2a_ia_x A_X + 2)= \ sum_ {i = 1}'「na_i 2-2a_x \ sum_ {i = 1} ^ + na_i na_x 2 \ ]

見つけることは困難で、限りの前処理として\(\ sum_ {i = 1 } ^ na_i ^ 2 \) と\(\ sum_ = {I}。1 na_i ^ \) それぞれについて\(X \)とすることができる直接\ (O(1)\)が算出されます。

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define LL long long
using namespace std;
int n,a[N+5];
int main()
{
    RI i;LL s=0,s2=0;for(scanf("%d",&n),i=1;i<=n;++i) scanf("%d",a+i),s+=a[i],s2+=1LL*a[i]*a[i];//预处理和及平方和
    for(i=1;i<=n;++i) printf("%lld ",s2-2*s*a[i]+1LL*n*a[i]*a[i]);return 0;//计算答案并输出
}

\(C \) ルーンエネルギー(表面タイトルを見るにはここをクリックしてください

:一般的な質問の意味は次の2つのアレイ(A、B \)\、インターバル期間が選択されてもよい([L、R&LT] \)\ので、(L \ルI \ル\ R \) すべて\(a_iを、b_i \)を乗じた\(K \)を探している、\(\ sum_ {i = 2 } a_iを\)^ nb_ {I-1}は最小値です。

これは、直接することができ、\(DP \)

我々は、セット\は(F_iと\)を選択し前記の表す\(Iは\)\(私は\)を最小変化値を得ることができる区間の期間の終わりではありません。

議論転送時間分割2例、一方が(私は\)\内部領域に、他方が(私は\)\間隔の始まりです。

\ [F_iと=分(F_ {I-1} + CL {I-1} a_iを(Q ^ 2-1)、CL {I-1} a_iを(K-1))\]

同時に、我々がするために使用するたびに(私は\)\値で最小の変更を更新するために、ケースの端のために:

\ [Mnは=分(N、F_ {I-1} + B_ {I-1} a_iを(K-1))\]

最終的な答えは、元の値を加えた最小の変化への答えです。

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define LL long long
#define min(x,y) ((x)<(y)?(x):(y))
#define Gmin(x,y) (x>(y)&&(x=(y)))
using namespace std;
int n,k,a[N+5],b[N+5];LL f[N+5];
int main()
{
    RI i;LL Mn=0,ans=0;for(scanf("%d%d",&n,&k),i=1;i<=n;++i) scanf("%d%d",a+i,b+i);//读入
    for(i=1;i<=n+1;++i) Gmin(Mn,f[i-1]+b[i-1]*a[i]*(k-1)),//更新最小变化值
        ans+=b[i-1]*a[i],f[i]=min(b[i-1]*a[i]*(k-1),f[i-1]+b[i-1]*a[i]*(k*k-1));//计算原先答案,并动态规划转移f[i]
    return printf("%lld",ans+Mn),0;//输出答案
}

\(D \) カイカイ野菜(問題の表面を見るにはここをクリックしてください

質問のおおよその意味は:有向グラフに、各時間値の範囲を求めては、直接右にして、この範囲内で接続されていない他の点間隔にポイントを見つけます。

我々は定義\(L_iを\)を用いて(私は\)\未満番号ポイント接続(Iは\)\の最大数、\(R_iを\)\が(私は\)より多い数の点を接続するIは(\ \)最小数。

現在のクエリ間隔設定\([L、R&LT]を\) 次いでポイントは、クエリに寄与する場合、それは満足している場合のみ。

\ [L_iを<L \ルI \ルR <R_iと\]

すなわち:

\ [L_iを+ 1 \ W \ C \ R \ R_iを-1 \]

その後、我々はオフライン考慮することができ、あなたがするように求められている(L \)\ソートを。

その後、我々は列挙\(Lの\)すべてのために、毎回\(L_iを+ 1 = Lの\ ) された\(私は\) 彼らは、そのメンテナンスフェンウィックツリー、条件を満たして\(I \シムr_i-を1 \)場所が追加されます\(a_iを\)

一方、\(1-Lの\)この場所は、インタロゲーション範囲内にないので、我々は(L-1 \ SIM R_ \ {L-1} -1 \) 位置が減算\(A_ {L-1} \) 。

尋ねられたときだけ頼む\(A_R \)の位置に値を。

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000000
#define swap(x,y) (x^=y^=x^=y)
#define Gmin(x,y) (x>(y)&&(x=(y)))
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n,m,Qt,a[N+5],l[N+5],r[N+5],L[N+5],R[N+5];
vector<int> s[N+5],q[N+5];vector<int>::iterator it;
class FastIO
{
    private:
        #define FS 100000
        #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
        #define tn (x<<3)+(x<<1)
        #define D isdigit(c=tc())
        char c,*A,*B,FI[FS];
    public:
        I FastIO() {A=B=FI;}
        Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
        Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
class TreeArray//树状数组
{
    private:
        #define lowbit(x) (x&-x)
        int v[N+5];
        I void Upt(RI x,CI y) {W(x<=n) v[x]+=y,x+=lowbit(x);}//修改后缀
    public:
        I void Add(CI l,CI r,CI v) {Upt(l,v),Upt(r+1,-v);}//区间修改,差分
        I int Qry(RI x,RI t=0) {W(x) t+=v[x],x-=lowbit(x);return t;}//单点询问
}T;
int main()
{
    RI i,x,y;long long ans=0;
    for(F.read(n,m,Qt),i=1;i<=n;++i) F.read(a[i]),l[i]=0,r[i]=n+1;//初始化
    for(i=1;i<=m;++i) F.read(x,y),x>y?Gmax(l[x],y):Gmin(r[x],y);//预处理l,r
    for(i=1;i<=n;++i) s[l[i]].push_back(i);//对于l[i]开桶,方便后面的操作
    for(i=1;i<=Qt;++i) F.read(L[i],R[i]),q[L[i]].push_back(i);//读入询问,并桶排
    for(i=1;i<=n;++i)//枚举L
    {
        i^1&&(T.Add(i-1,r[i-1]-1,-a[i-1]),0);//删去L-1的贡献
        for(it=s[i-1].begin();it!=s[i-1].end();++it) T.Add(*it,r[*it]-1,a[*it]);//对于所有l[i]+1=L的i,加上其贡献
        for(it=q[i].begin();it!=q[i].end();++it) ans^=1LL*(*it)*T.Qry(R[*it]);//枚举R询问
    }return printf("%lld",ans),0;
}

\(E \) マジック機能(問題の表面を見るにはここをクリックしてください

一般的な質問の意味: \(D(X)\)\(X \)よりも大きい\(1 \)最小因子、\(F(X)= \ケース開始{1} = X&\\ D 1(X )F(\ X FRAC {D(X)^ 2})&D(X)^ 2 | X \\ F(\ X FRAC {D(X)})&その他ケースに終わりを{} \ \) 求めている\ (\ sum_ = {I}。1 ^ NF(I)\)

我々は設定\(X = \ sum_ {I = 1} ^ tp_i ^ {C_I} \)、次いで\(F(X)= \ sum_ {i = 1} ^ tp_i ^ {\ lfloorの\のFRAC {C_I} 2 \ } rfloor \) 次のように証明します:

(P_I \)\、もし\(C_I \ GE 2 \)によって、\(F(X)= D (x)は、F(\ FRACのX {D(X)^ 2})\(D(X )^ 2 | X)\)排除する\(X \) 2 \(P_I \)を、与えるために\に(F(X)を\)\(1 \)\(P_I \) その\(C_I \)数で割った\(2 \)

IFおよび\(1 C_I = \)\(F(x)はF = (\ FRACのX {D(x)})\他は\) に置くであろう\(P_I \)に加えて、即ち、消失を二つに切り捨て。

次に、\(F(N)\)明らかに\(O(\ SQRT N) \) レベル。

だから我々は、列挙することができます\(F(I)\) 提供\(G(X)を\)を表す\(\ nは1 \ SIM)無平方のカウント数を、答えは次のとおりです。

\ [\ sum_ {i = 1} ^ {\のSQRTのn}はI \ CDOT G(\ lfloorの\のFRAC N {I ^ 2} \ rfloor)\]

前記\(G \)有意平方因子を含む数ならば、ということである\(K ^ 2 \)は、その\(F \)値であろう(IK \)\、それは係数が二乗含有すべきではありません。

次に考える\(G \)を使用することができる包含および除外の値を求めるための方法を、ボリューム係数は忌避である\(\ MU \) そう:

\ [G(X)= \ sum_ {i = 1} ^ {\ SQRT X}ミュー(I)\ lfloor \ FRAC N {I ^ 2} \ rfloor \ \]

ここでは上記の答えは、とのために\(G \) 我々はすぐ比較的に評価分裂を阻止するために使用することができますが、立ち往生しているようです。

だから我々はアウトを事前に持っている(のxの\ le10 ^ 7 \ \ ) の\(G(X-)\)私たちは前にできるように、。

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define LS 10000000
#define LL long long
using namespace std;
LL n;
template<int SZ> class LinearSieve//线性筛
{
    private:
        int Pt,P[SZ+5],mu[SZ+5];
    public:
        LL smu[SZ+5],smu2[SZ+5];
        I LinearSieve()
        {
            RI i,j;for(mu[1]=1,i=2;i<=LS;++i)
                for(!P[i]&&(mu[P[++Pt]=i]=-1),j=1;j<=Pt&&1LL*i*P[j]<=SZ;++j)
                    if(P[i*P[j]]=1,i%P[j]) mu[i*P[j]]=-mu[i];else break;
            for(i=1;i<=LS;++i) smu[i]=smu[i-1]+mu[i],smu2[i]=smu2[i-1]+mu[i]*mu[i];//筛mu和以及平方和
        }
};LinearSieve<LS> L;
I LL G(Con LL& x)
{
    if(x<=LS) return L.smu2[x];RI l,r,sx=sqrt(x);LL res=0;//x较小时直接返回答案
    for(l=1;l<=sx;l=r+1) r=sqrt(x/(x/(1LL*l*l))),res+=x/(1LL*l*l)*(L.smu[r]-L.smu[l-1]);//除法分块
    return res;//返回答案
}
int main()
{
    RI Tt,l,r,sn;LL ans=0;scanf("%d",&Tt);W(Tt--)
    {
        scanf("%lld",&n),sn=sqrt(n),ans=0;//读入
        for(l=1;l<=sn;l=r+1) r=sqrt(n/(n/(1LL*l*l))),ans+=G(n/(1LL*l*l))*(l+r)*(r-l+1)>>1;//除法分块
        printf("%lld\n",ans);//输出答案
    }return 0;
}

\(F \) ゴールド・エクスペリエンス(問題の表面を見るにはここをクリックしてください

だから、難しい話題、私は明らかにしないだろう。

充填するピットを離れます。

おすすめ

転載: www.cnblogs.com/chenxiaoran666/p/CometOJ8.html