zoukankan      html  css  js  c++  java
  • luogu P4156 [WC2016]论战捆竹竿

    upd:19.12.19

    重新写了这道题,并且修正了原来题解描述中一些奇怪的东西

    然后重新发出来假装根了脖


    luogu

    uoj

    官方题解(证明都在这)

    神仙题鸭qwq

    转化模型,如果原串存在一个长度为(i(i<n))(mathrm{border}),那么每次可以往后面加(n-i)的长度,所以这题本质是有一个集合(这题里(n)也属于这个集合),每次可以往后面加上集合内的一个数,问在给定范围内能凑出来的数的数量

    这显然是同余类最短路,枚举集合中一个数(a_1)作为模数,然后求出(di_i)表示模(a_1)意义下为(i)的数中能凑出来的最小数

    这个暴力是可以优化成(O(n|S|))的.具体操作是枚举每个数(a_i),然后只用这个数往后跳,这样在膜(m)意义下可以形成(gcd(a_i,m))个环.对每个环找到(di)最小的点,从这个点开始依次遍历整个环,更新后一个位置

    有个结论是集合中的数(也就是所有合法(mathrm{border})长度)可以分成(logn)个等差数列,所以可以枚举每个等差数列贡献答案.具体的设某个等差序列首项为(b),公差为(d),项数为(l),然后当前同余最短路模数为(a),先把模(a)意义的最短路转成模(b)意义的最短路.具体操作是用模(a)意义下的所有(di)更新模(b)意义下的一些(di),然后从每个环的最小(di)处以(a)为跳跃距离更新其他的点.对于公差的贡献,相当于每个位置以(d)作为跳跃距离往后跳最多(l-1)次,然后转移跳到的位置,转移大概为(forall k in [1,l-1],di_{(x+dk)\% b}=min(di_{(x+dk)\% b},di_x+b+dk)),这个东西用个单调队列优化转移即可.

    #include<bits/stdc++.h>
    #define LL long long
    #define uLL unsigned long long
    
    using namespace std;
    const int N=5e5+10;
    LL rd()
    {
    	LL x=0,w=1;char ch=0;
    	while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    	return x*w;
    }
    int ad(int x,int y,int z){x+=y,x-=x>=z?z:0;return x;}    //加上这个就能过extest了~~然后垫底~~
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    uLL ha[N],hb[N],b1=233,hha[N],hhb[N],b2=677,mod=993244853;
    int n,a[N],m,hd,tl;
    LL di[N],d2[N],ln,q[N][2];
    char cc[N];
    
    int main()
    {
    	freopen("1.in","r",stdin);
    	freopen("1.out","w",stdout);
    	int T=rd();
    	while(T--)
    	{
    		n=rd(),ln=rd()-n;
    		scanf("%s",cc+1);
    		for(int i=1;i<=n;++i)
    			ha[i]=ha[i-1]*b1+cc[i],hha[i]=(1ll*hha[i-1]*b2%mod+cc[i])%mod;
    		uLL p1=1,p2=1;
    		hb[n+1]=hhb[n+1]=0;
    		for(int i=n;i;--i)
    		{
    			hb[i]=hb[i+1]+cc[i]*p1,hhb[i]=(hhb[i+1]+1ll*cc[i]*(int)p2%mod)%mod;
    			p1*=b1,p2=p2*b2%mod;
    		}
    		m=0;
    		for(int i=n-1;i;--i)
    			if(ha[i]==hb[n-i+1]&&hha[i]==hhb[n-i+1]) a[++m]=n-i;
    		int sz=n;
    		memset(di,0x3f3f3f,sizeof(LL)*(n+1));
    		di[0]=0;
    		for(int l=1,r=1+(m>1);l<=m;l=r+1,r=r+2)
    		{
    			r=min(r,m);
    			int dx=a[l+1]-a[l];
    			while(r<m&&dx==a[r+1]-a[r]) ++r;
    			memset(d2,0x3f3f3f,sizeof(LL)*(a[l]+1));
    			for(int i=0;i<sz;++i)
    				d2[di[i]%a[l]]=min(d2[di[i]%a[l]],di[i]);
    			memcpy(di,d2,sizeof(LL)*(a[l]+1));
    			int jp=gcd(sz,a[l]),zz=sz%a[l];;
    			for(int i=0;i<jp;++i)
    			{
    				int np=i;
    				for(int j=ad(i,zz,a[l]);j!=i;j=ad(j,zz,a[l]))
    					if(di[np]>di[j]) np=j;
    				for(int j=ad(np,zz,a[l]),ls=np;j!=np;j=ad(j,zz,a[l]),ls=ad(ls,zz,a[l]))
    					di[j]=min(di[j],di[ls]+sz);
    			}
    			sz=a[l];
    			if(l==r) continue;
    			jp=gcd(sz,dx),zz=dx%sz;
    			for(int i=0;i<jp;++i)
    			{
    				int np=i;
    				for(int j=ad(i,zz,sz);j!=i;j=ad(j,zz,sz))
    					if(di[np]>di[j]) np=j;
    				hd=1,q[tl=1][0]=di[np],q[tl][1]=0;
    				for(int j=ad(np,zz,sz),k=1;j!=np;j=ad(j,zz,sz),++k)
    				{
    					while(hd<=tl&&k-q[hd][1]>r-l) ++hd;
    					if(hd<=tl) di[j]=min(di[j],q[hd][0]+sz+1ll*dx*k);
    					while(hd<=tl&&q[tl][0]>=di[j]-1ll*dx*k) --tl;
    					q[++tl][0]=di[j]-1ll*dx*k,q[tl][1]=k;
    				}
    			}
    		}
    		LL ans=0;
    		for(int i=0;i<sz;++i) ans+=max((ln-di[i]+sz)/sz,0ll);
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    1.27
    1.25
    Representation Learning with Contrastive Predictive Coding
    Learning a Similarity Metric Discriminatively, with Application to Face Verification
    噪声对比估计(负样本采样)
    Certified Adversarial Robustness via Randomized Smoothing
    Certified Robustness to Adversarial Examples with Differential Privacy
    Dynamic Routing Between Capsules
    Defending Adversarial Attacks by Correcting logits
    Visualizing Data using t-SNE
  • 原文地址:https://www.cnblogs.com/smyjr/p/10264389.html
Copyright © 2011-2022 走看看