zoukankan      html  css  js  c++  java
  • 2021ccpc预选

    A

    签到题,分别计算两种情况边的贡献,注意奇偶性的影响

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 100100
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pls(a,b) (a+b)%MOD
    #define mns(a,b) (a-(b))%MOD
    #define mul(a,b) (1LL*(a)*(b))%MOD
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,ans,x;
    int main()
    {
    	rep(T,1,read())
    	{
    		n=read();ans=n-n/2;
    		x=(n+2)/3;if(x&1) ans++,x++;
    		ans+=(n-x+1)/2;
    		printf("%d
    ",ans);
    	}
    }
    

    B

    先将整个串处理出来,寻找合法区间可以简单用滑动窗口维护

    容易发现(n imes lcm(len_1,cdots,len_n))为一个周期,而(lcm)很小

    由于字符串是循环的,因此考虑到([0,2lcm])区间即一定存在答案

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 6001001
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    int n,m,lcm,len[110],pos,sum[26],tot,vis[26],now,ans;
    char ch[110][15],s[MAXN];
    inline void mdf(int x,int w)
    {
    	sum[x]+=w;
    	if(w>0&&sum[x]==1) now++;
    	if(w<0&&!sum[x]) now--;
    }
    int main()
    {
    	int g;rep(T,1,read())
    	{
    		n=read();lcm=pos=1;m=tot=now=0;ans=inf;
    		rep(i,0,25) vis[i]=sum[i]=0;
    		rep(i,1,n)
    		{
    			scanf("%s",ch[i]);len[i]=strlen(ch[i]);
    			g=__gcd(lcm,len[i]),lcm=lcm/g*len[i];
    			rep(j,0,len[i]-1) if(!vis[ch[i][j]-'a']) vis[ch[i][j]-'a']=1,tot++;
    		}
    		rep(i,0,lcm*2-1) rep(j,1,n) s[++m]=ch[j][i%len[j]];
    		rep(i,1,m) 
    		{
    			mdf(s[i]-'a',1);
    			for(;now==tot;pos++) ans=min(ans,i-pos+1),mdf(s[pos]-'a',-1);
    		}
    		printf("%d
    ",ans);
    	}
    }
    

    E

    令矩阵(A=egin{bmatrix}b&c\ 1&0end{bmatrix})(B=egin{bmatrix}d&e\ 1&0end{bmatrix}),容易得到(egin{bmatrix}f(i+j,i)\...end{bmatrix}=B^{j}A^{i-1}egin{bmatrix}a\ 0end{bmatrix}=egin{bmatrix}B^j_{1,1}&B^j_{1,2}\ B^j_{2,1}&B^j_{2,2}end{bmatrix}egin{bmatrix}A^{i-1}_{1,1}&A^{i-1}_{1,2}\ A^{i-1}_{2,1}&A^{i-1}_{2,2}end{bmatrix}egin{bmatrix}a\ 0end{bmatrix})

    即:(f(i+1,i)=(B^j_{1,1}A^{i-1}_{1,1}+B^j_{1,2}A^{i-1}_{2,1})cdot a)

    代入得:

    [egin{aligned} sumlimits_{i=1}^nsumlimits_{j=1}^ninom{i+j}{i}f(i+j,i)&=sumlimits_{i=1}^nsumlimits_{j=1}^ninom{i+j}{i}(B^j_{1,1}A^{i-1}_{1,1}+B^j_{1,2}A^{i-1}_{2,1})cdot a\ &=asumlimits_{i=1}^nsumlimits_{j=1}^nfrac{(i+j)!}{i!j!}(B^j_{1,1}A^{i-1}_{1,1}+B^j_{1,2}A^{i-1}_{2,1})\ end{aligned} ]

    此时预处理出(A,B)矩阵的幂次之后就可以使用(ntt)计算,但需要比较优秀的常数

    下面的代码是正确的,但因为常数T掉了

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 200100
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    struct Matrix
    {
    	int w[2][2];
    	void init(int a=0,int b=0,int c=0,int d=0){w[0][0]=a,w[0][1]=b,w[1][0]=c,w[1][1]=d;}
    	Matrix operator * (const Matrix &t)
    	{
    		static Matrix res;res.init();
    		rep(i,0,1) rep(j,0,1) rep(k,0,1)
    			inc(res.w[i][j],mul(w[i][k],t.w[k][j]));
    		return res;
    	}
    }pw1[MAXN],pw2[MAXN],k1,k2,one;
    int n,a,b,c,d,e,ans;
    int A[MAXN<<1],B[MAXN<<1],fac[MAXN],ifac[MAXN];
    int rev[MAXN<<1],lim,lg,pw[30],ipw[30];
    int q_pow(int bas,int t,int res=1)
    {
        for(;t;t>>=1,bas=mul(bas,bas)) if(t&1) res=mul(res,bas);return res;
    }
    #define inv(x) q_pow(x,MOD-2)
    void ntt(int *a,int n,int f)
    {
        rep(i,0,n-1) if(i<rev[i]) swap(a[i],a[rev[i]]);
        for(int i=1,t=1;i<n;i<<=1,++t)
        {
            int wn= f>0?pw[t]:ipw[t];for(int j=0;j<n;j+=i<<1)
            {
                int w=1,x,y;for(int k=0;k<i;++k,w=mul(w,wn))
                    x=a[j+k],y=mul(a[j+k+i],w),a[j+k]=pls(x,y),a[j+k+i]=mns(x,y);
            }
        }
        if(f>0) return ;int nv=inv(n);rep(i,0,n-1) a[i]=mul(a[i],nv);
    }
    int main()
    {
    	one.init(1,0,0,1);pw1[0]=pw2[0]=one,ans=0;
    	fac[0]=ifac[0]=1;rep(i,1,2e5) fac[i]=mul(fac[i-1],i),ifac[i]=inv(fac[i]);
    	rep(T,1,read())
    	{
    		n=read(),a=read(),b=read(),c=read(),d=read(),e=read();
    		k1.init(b,c,1,0);k2.init(d,e,1,0);ans=0;
    		rep(i,1,n) pw1[i]=pw1[i-1]*k1,pw2[i]=pw2[i-1]*k2;
    	    for(lim=1,lg=1;lim<(n+1<<1);lim<<=1,lg++)
    	        pw[lg]=q_pow(3,(MOD-1)/(1<<lg)),ipw[lg]=inv(pw[lg]);
    	    rep(i,1,lim-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-2);
    	    rep(i,1,n) A[i]=mul(pw1[i-1].w[0][0],ifac[i]);
    	    rep(i,1,n) B[i]=mul(pw2[i].w[0][0],ifac[i]);
    	    B[0]=0;rep(i,n+1,lim-1) A[i]=B[i]=0;
    	    ntt(A,lim,1);ntt(B,lim,1);rep(i,0,lim-1) A[i]=mul(A[i],B[i]);ntt(A,lim,-1);
    	    rep(i,0,2*n) tms(A[i],fac[i]),inc(ans,A[i]);
    	    rep(i,1,n) A[i]=mul(pw1[i-1].w[1][0],ifac[i]);
    	    rep(i,1,n) B[i]=mul(pw2[i].w[0][1],ifac[i]);
    	    B[0]=0;rep(i,n+1,lim-1) A[i]=B[i]=0;
    	    ntt(A,lim,1);ntt(B,lim,1);rep(i,0,lim-1) A[i]=mul(A[i],B[i]);ntt(A,lim,-1);
    	    rep(i,0,2*n) tms(A[i],fac[i]),inc(ans,A[i]);
    	    
    	    tms(ans,a);
    	    printf("%d
    ",ans);
    	}
    }
    

    考虑一个线性递推的过程,令矩阵(F_j=sumlimits_{i=1}^ninom{i+j}{i}B^jA^{i-1}),则最终答案为(sumlimits_{j=1}^nF_jegin{bmatrix}a\0end{bmatrix})

    而:

    [egin{aligned} F_{j+1}&=sumlimits_{i=1}^ninom{i+j+1}{i}B^{j+1}A^{i-1}\ &=sumlimits_{i=1}^nleft[inom{i+j}{i}+inom{i+j}{i-1} ight]B^{j+1}A^{i-1}\ &=Bsumlimits_{i=1}^ninom{i+j}{i}B^jA^{i-1}+sumlimits_{i=1}^ninom{i+j}{i-1}B^{j+1}A^{i-1}\ &=BF_j+sumlimits_{i=0}^{n-1}inom{i+j+1}{i}B^{j+1}A^i\ &=BF_j+sumlimits_{i=1}^ninom{i+j+1}{i}B^{j+1}A^i+B^{j+1}A^0-inom{n+j+1}{n}B^{j+1}A^n\ &=BF_j+left[sumlimits_{i=1}^ninom{i+j+1}{i}B^{j+1}A^{i-1} ight]A+B^{j+1}-inom{n+j+1}{n}B^{j+1}A^n\ &=BF_j+F_{j+1}A+B^{j+1}-inom{n+j+1}{n}B^{j+1}A^n\ end{aligned} ]

    移项得:

    [F_{j+1}(I-A)=BF_j+B^{j+1}-inom{n+j+1}{n}B^{j+1}A^n ]

    由于(I-A=egin{bmatrix}1-b&-c\-1&1end{bmatrix}) 一定满秩,其逆矩阵一定存在,((I-A)^{-1}=frac{1}{1-b-c}egin{bmatrix}1&c\1&1-bend{bmatrix})

    则:

    [F_{j+1}=left[BF_j+B^{j+1}-inom{n+j+1}{n}B^{j+1}A^n ight](I-A)^{-1} ]

    由此即可在(O(omega^3))的复杂度内递推得到(F_{j+1})

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 200100
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    struct Matrix
    {
    	int w[2][2];
    	void init(int a=0,int b=0,int c=0,int d=0){w[0][0]=a,w[0][1]=b,w[1][0]=c,w[1][1]=d;}
    	Matrix operator * (const Matrix &t)
    	{
    		static Matrix res;res.init();
    		rep(i,0,1) rep(j,0,1) rep(k,0,1)
    			inc(res.w[i][j],mul(w[i][k],t.w[k][j]));
    		return res;
    	}
    	Matrix operator + (const Matrix &t)
    	{
    		static Matrix res;res.init();
    		rep(i,0,1) rep(j,0,1)
    			res.w[i][j]=pls(w[i][j],t.w[i][j]);
    		return res;
    	}
    	Matrix operator - (const Matrix &t)
    	{
    		static Matrix res;res.init();
    		rep(i,0,1) rep(j,0,1)
    			res.w[i][j]=mns(w[i][j],t.w[i][j]);
    		return res;
    	}
    	Matrix operator * (const int &t)
    	{
    		static Matrix res;
    		rep(i,0,1) rep(j,0,1) res.w[i][j]=mul(w[i][j],t);
    		return res;
    	}
    }pw1[MAXN],pw2[MAXN],k1,k2,one,invm,res;
    int n,a,b,c,d,e,fac[MAXN],ifac[MAXN],ans;
    inline int C(int n,int m)
    {
    	if(n<0||n<m) return 0;
    	return mul(fac[n],mul(ifac[m],ifac[n-m]));
    }
    int main()
    {
    	one.init(1,0,0,1);pw1[0]=pw2[0]=one,ans=0;fac[0]=ifac[0]=1;
    	rep(i,1,2e5) fac[i]=mul(fac[i-1],i),ifac[i]=Inv(fac[i]);
    	rep(T,1,read())
    	{
    		n=read(),a=read(),b=read(),c=read(),d=read(),e=read();
    		k1.init(b,c,1,0);k2.init(d,e,1,0);ans=0;res.init();
    		invm.init(1,c,1,mns(1,b));invm=invm*Inv(mns(1,b+c));
    		rep(i,1,n) pw1[i]=pw1[i-1]*k1,pw2[i]=pw2[i-1]*k2;
    		rep(i,1,n) res=res+pw2[1]*pw1[i-1]*(i+1);
    		inc(ans,res.w[0][0]);
    		rep(i,2,n)
    		{
    			res=(k2*res+pw2[i]-pw2[i]*pw1[n]*C(n+i,n))*invm;
    			inc(ans,res.w[0][0]);
    		}
    	    tms(ans,a);
    	    printf("%d
    ",ans);
    	}
    }
    

    F

    注意到((x-2)^2+(x+1)^2-(x-1)^2-x^2=4)

    因此我们可以构造出(1,2,3,4)的方案后直接在串后添加若干个(1001)即可

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 1001001
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,lim=1e6;
    char s[MAXN];
    int main()
    {
    	rep(i,1,lim) s[i]='1',s[i+1]='0',s[i+2]='0',s[i+3]='1',i=i+3;
    	rep(T,1,read())
    	{
    		scanf("%d",&n);
    		if(n%4==1) printf("%d
    1",n);
    		else if(n%4==2) printf("%d
    0001",n+2);
    		else if(n%4==3) printf("%d
    01",n-1);
    		else printf("%d
    ",n);
    		n=(n/4)*4;
    		printf("%s",s+lim-n+1);puts("");
    	}
    }
    

    G

    对于(g(x))相同的数,函数为关于(x)的二次函数,而(g(x))的取值很小

    因此预处理出每个(g(x))的所有(x),每次三分求出这个(g(x))的最小值

    #include<bits/stdc++.h>
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 1001001
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    ll n,a,b,c,d;
    const ll inf=1e18;
    ll res,ans;
    vector<int> g[60];
    inline int calc(int x,int res=0){while(x) res+=x%10,x/=10;return res;}
    inline ll getw(ll x,ll y){return a*x*x*y+b*x*x+c*x*y*y+d*x*y;}
    void mem(int n=1e6) {rep(i,1,n) g[calc(i)].pb(i);}
    int main()
    {
    	mem();int l,r,ml,mr;ll al,ar;
    	rep(T,1,read())
    	{
    		a=read(),b=read(),c=read(),d=read(),n=read();ans=inf;
    		rep(i,1,54)
    		{
    			res=inf;l=0,r=upper_bound(g[i].begin(),g[i].end(),n)-g[i].begin()-1;
    			for(;l<r;)
    			{
    				ml=l+r>>1;mr=ml+1;
    				al=getw(g[i][ml],i),ar=getw(g[i][mr],i);
    				res=min(res,min(al,ar));
    				if(al<ar) r=mr-1;else l=ml+1;
    			}
    			if(l==r) res=min(res,getw(g[i][l],i));
    			ans=min(ans,res);
    		}
    		printf("%lld
    ",ans);
    	}
    }
    

    H

    考虑枚举(gcd),每次在数列中找到(gcd)的所有倍数,令排序后这些数的位置数组为(pos)

    则满足(lle p_i,rge p_{i+1},1le i< lfloorfrac{n}{g} floor)的所有区间([l,r])答案至少为(g)

    因此可以倒着枚举(gcd),每次第一个被修改的([l,r])答案即为(g)

    考虑用线段树维护每个(l)被修改过的(r)最小值

    直接做的话显然需要维护区间和并支持区间取(min)操作,似乎需要(segment tree beats!)

    但实际并不需要,由于每次修改的(l,r)都是单增的,因此整个线段树维护的值也一定是单调的

    可以再维护区间最大值,每次在线段树上二分出需要被修改的区间,线段树只需要支持区间赋值,区间求和即可

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 100100
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    int n,g[MAXN],p[MAXN],pos[MAXN],m;
    int tag[MAXN<<2],mx[MAXN<<2];
    ll sum[MAXN<<2],ans[MAXN];
    inline void Mdf(int k,int l,int r,int w)
    {
    	tag[k]=w,sum[k]=1LL*(r-l+1)*w,mx[k]=w;
    }
    inline void pshd(int k,int l,int r,int mid)
    {
    	Mdf(k<<1,l,mid,tag[k]);Mdf(k<<1|1,mid+1,r,tag[k]);
    	tag[k]=0;
    }
    inline void upd(int k)
    {
    	sum[k]=sum[k<<1]+sum[k<<1|1], 
    	mx[k]=max(mx[k<<1],mx[k<<1|1]);
    }
    void build(int k,int l,int r)
    {
    	tag[k]=0;if(l==r) {sum[k]=mx[k]=n+1;return ;}
    	int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    	upd(k);
    }
    void mdf(int k,int l,int r,int a,int b,int w)
    {
    	if(a<=l&&r<=b) {Mdf(k,l,r,w);return ;}
    	int mid=l+r>>1;if(tag[k]) pshd(k,l,r,mid);
    	if(a<=mid) mdf(k<<1,l,mid,a,b,w);
    	if(b>mid) mdf(k<<1|1,mid+1,r,a,b,w);
    	upd(k);
    }
    int find(int k,int l,int r,int x)
    {
    	if(l==r) return sum[k]>x?l:n+1;int mid=l+r>>1;
    	if(tag[k]) pshd(k,l,r,mid);
    	return mx[k<<1]<=x?find(k<<1|1,mid+1,r,x):find(k<<1,l,mid,x);
    }
    ll query(int k,int l,int r,int a,int b)
    {
    	if(a<=l&&r<=b) return sum[k];int mid=l+r>>1;ll res=0;
    	if(tag[k]) pshd(k,l,r,mid);
    	if(a<=mid) res+=query(k<<1,l,mid,a,b);
    	if(b>mid) res+=query(k<<1|1,mid+1,r,a,b);
    	return res;
    }
    int main()
    {
    	int l,r;rep(T,1,read())
    	{
    		n=read();
    		rep(i,1,n) g[i]=read(),pos[g[i]]=i,ans[i]=0;
    		build(1,1,n);
    		dwn(i,n/2,2)
    		{
    			m=0;for(int j=i;j<=n;j+=i) p[++m]=pos[j];
    			sort(p+1,p+m+1);
    			rep(j,1,m-1)
    			{
    				r=p[j],l=find(1,1,n,p[j+1]);
    				if(l>r) continue;
    				ans[i]+=query(1,1,n,l,r)-1LL*p[j+1]*(r-l+1);
    				mdf(1,1,n,l,r,p[j+1]);
    			}
    		}
    		ans[1]=1LL*n*(n-1)/2;
    		rep(i,2,n) ans[1]-=ans[i];
    		rep(i,1,n) printf("%lld
    ",ans[i]);
    	}
    }
    

    I

    签到题,(map)记录每个(pair)的出现次数

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 1001001
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    int n;char s[MAXN];ll ans;
    map<pii,int> m;
    int main()
    {
    	int x,y;rep(T,1,read())
    	{
    		n=read();scanf("%s",s+1);
    		m.clear();x=y=0;m[{0,0}]=1;ans=0;
    		rep(i,1,n)
    		{
    			if(s[i]=='U') y++;if(s[i]=='D') y--;
    			if(s[i]=='R') x++;if(s[i]=='L') x--;
    			ans+=m[{x,y}];m[{x,y}]++;
    		}
    		printf("%lld
    ",ans);
    	}
    }
    

    K

    可以先预处理每一列净消耗若干个子弹获得的最大代价,基本转化为了普通背包

    问题在于无论怎么选择,最后一颗子弹打完之后就不能继续获得当前局面下净花费为(0)的价值了

    因此我们(dp)多一维(0/1),表示是否有选择某一个物品为结束时的花费

    转移依然很简单,最终答案全部打完子弹且有选择结束的(dp)

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 1001001
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    char ch[5];
    int n,m,k,f[220][220][2],w[220][220],ed[220][220];
    int a[220][220],ok[220][220],mx[220],lft[220];
    int main()
    {
    	rep(T,1,read())
    	{
    		n=read(),m=read(),k=read();
    		rep(i,1,n) rep(j,1,m)
    		{
    			scanf("%d%s",&a[i][j],ch);ok[i][j]=(ch[0]=='Y')?1:0;
    		}
    		rep(j,1,m)
    		{
    			w[j][mx[j]=0]=0;
    			dwn(i,n,1)
    			{
    				if(!ok[i][j]) w[j][mx[j]+1]=w[j][mx[j]],mx[j]++,ed[j][mx[j]]=w[j][mx[j]]+a[i][j];
    				w[j][mx[j]]+=a[i][j];
    			}
    		}
    		rep(i,0,m) rep(j,0,k) f[i][j][0]=f[i][j][1]=-inf;f[0][k][0]=0;
    		rep(i,1,m) rep(j,0,k) 
    		{
    			f[i][j][1]=f[i-1][j][1]+w[i][0];
    			if(j) f[i][j][0]=f[i-1][j][0]+w[i][0];
    			else f[i][j][0]=f[i-1][j][0];
    			rep(l,1,min(mx[i],k-j))
    			{
    				f[i][j][0]=max(f[i][j][0],f[i-1][j+l][0]+w[i][l]),
    				f[i][j][1]=max(f[i][j][1],f[i-1][j+l][0]+ed[i][l]),
    				f[i][j][1]=max(f[i][j][1],f[i-1][j+l][1]+w[i][l]);
    			}
    		}
    		printf("%d
    ",f[m][0][1]);
    	}
    }
    

    L

    因为答案是单增的,所以对于数(x),需要找到最前面的点来转移即找到一个(p)使(x-x mod p)最小

    我们可以开一个小根堆来记录每个质数当前的倍数,每次找到符合条件的最小值转移

    如果该质数对应的倍数过小则用本次的(x)来更新,每一个质数至多被(pop lceilfrac{N}{p} ceil)

    因此复杂度为(O(Nlog P+P log Ploglog n))可以通过

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 2001001
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    struct Data{int w,pos;}res;
    bool operator < (Data x,Data y){return x.pos>y.pos;}
    priority_queue<Data> q;
    int N,m,n,p[MAXN],ans[MAXN];
    ull pw[MAXN],sum;ll lcm;
    int main()
    {
    	pw[0]=1;rep(i,1,2e6) pw[i]=pw[i-1]*23333;
    	rep(T,1,read())
    	{
    		N=m=read(),n=read();sum=0,lcm=1;
    		rep(i,1,n) {p[i]=read();q.push({p[i],0});if(lcm-1<m) lcm*=p[i];}
    		if(lcm-1<m) m=lcm-1;
    		rep(i,1,m)
    		{
    			for(res=q.top();i/res.w*res.w!=res.pos;res=q.top())
    				{q.pop();res.pos=i/res.w*res.w;q.push(res);}
    			ans[i]=ans[res.pos]+1,sum+=pw[N-i]*ans[i];
    		}
    		printf("%llu
    ",sum);
    		while(!q.empty()) q.pop();
    	}
    }
    
  • 相关阅读:
    Python超轻量数据库之SQLite
    Docker镜像管理透析
    Docker-Compose实战「下篇」
    Docker-Compose实战「上篇」
    Docker-Compose初体验
    Docker火遍全球!dockerfile构建你必须得会
    Docker轻量管理Dashboard
    MongoDB入门实操《上篇》
    用LinkedList完成一个堆栈MyStack.2
    [翻译] 基于.NET Core构建微服务 第五部分:Marten域聚合的理想仓库
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/15223836.html
Copyright © 2011-2022 走看看