zoukankan      html  css  js  c++  java
  • 「考试总结」20200724初音

    A.字符串识别

    Description

    link

    Solution

    这题问题出在了对于一个后缀自动机,这里如果在 (DAG) 上面进行操作,复杂度是 (O(n^2))

    所以我们换个思路做,还是考虑那些 (endpos) 集合大小为 (1) 的字符串

    看看贡献:

    [iin [i-len_{fa_i}+1,i] ans_i=min(ans_i,len_{fa_i}+1) ]

    [iin[i-len_i+1,i-len_{fa_i}] ans_i=min(ans_i,len_p-i+1) ]

    对于第一种情况,线段树统计答案

    对于第二种情况,观察到 (ans_i) 这一项总是加着一个 (i)

    那么先统一加上,然后最后面减掉,对位置减就好的

    另外,区间取 (min) 的线段树,需要好好记得怎么写……

    Code

    #include<bits/stdc++.h>
    using namespace std;
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=5e5+10,M=15e5+10;
    	int ans[N],le;
    	struct SGT{
    		int maxx[N<<2];
    		#define maxx(p) maxx[p]
    		inline void build(int p,int l,int r,int val)
    		{
    			if(l==r) return maxx(p)=le+l*val,void();
    			int mid=(l+r)>>1; build(p<<1,l,mid,val); build(p<<1|1,mid+1,r,val);
    			return maxx(p)=2e9+10,void();
    		}
    		inline void update(int p,int st,int ed,int l,int r,int val)
    		{
    			if(l<=st&&ed<=r) return maxx(p)=min(maxx(p),val),void();
    			int mid=(st+ed)>>1; 
    			if(l<=mid) update(p<<1,st,mid,l,r,val);
    			if(r>mid) update(p<<1|1,mid+1,ed,l,r,val); 
    			return ;
    		}		
    		inline void work(int p,int st,int ed,int val)
    		{
    			if(st==ed)
    			{
    				ans[st]=min(ans[st],maxx(p)-val*st);
    				return ;
    			} 
    			int mid=(st+ed)>>1;
    			maxx(p<<1)=min(maxx(p<<1),maxx(p));
    			maxx(p<<1|1)=min(maxx(p<<1|1),maxx(p));
    			work(p<<1,st,mid,val); work(p<<1|1,mid+1,ed,val);
    			return ;
    		}
    	}T1,T2;
    	struct edg{
    		int to,nxt;
    	}e[M<<1];
    	int head[M],cnt;
    	inline void add(int u,int v)
    	{
    		e[++cnt].to=v; e[cnt].nxt=head[u];
    		return head[u]=cnt,void();
    	}
    	int son[M][26],fa[M],len[M],tot=1,r[M],las=1,sz[M];
    	inline void copy(int x,int y)
    	{
    		for(int i=0;i<26;++i) son[x][i]=son[y][i];
    		return ;
    	} 
    	inline void extend(int x,int id)
    	{
    		int tmp=las,np=las=++tot; len[np]=len[tmp]+1; sz[np]=1; r[np]=id;
    		while(tmp&&!son[tmp][x]) son[tmp][x]=np,tmp=fa[tmp];
    		if(!tmp) return fa[np]=1,void();
    		int q=son[tmp][x];
    		if(len[q]==len[tmp]+1) return fa[np]=q,void();
    		int clone=++tot; len[clone]=len[tmp]+1;
    		fa[clone]=fa[q],fa[np]=fa[q]=clone; copy(clone,q); r[clone]=x;
    		while(tmp&&son[tmp][x]==q) son[tmp][x]=clone,tmp=fa[tmp];
     		return ;
    	} 
    	inline void dfs(int x)
    	{
    		for(int i=head[x];i;i=e[i].nxt)
    		{
    			int t=e[i].to; dfs(t); 
    			sz[x]+=sz[t];
    		}
    		if(sz[x]==1) 
    		{
    			T1.update(1,1,le,r[x]-len[fa[x]]+1,r[x],len[fa[x]]+1);
    			T2.update(1,1,le,r[x]-len[x]+1,r[x]-len[fa[x]],len[x]+1);
    		}
    		return ;
    	}	
    	char s[N];
    	signed main()
    	{
    		memset(ans,0x3f,sizeof(ans));
    		scanf("%s",s+1); le=strlen(s+1); 
    		T1.build(1,1,le,0); 
    		T2.build(1,1,le,1); 
    		for(int i=1;i<=le;++i) extend(s[i]-'a',i); 
    		for(int i=1;i<=tot;++i) add(fa[i],i); dfs(1);
    		T1.work(1,1,le,0); 
    		T2.work(1,1,le,1);
    		for(int i=1;i<=le;++i) printf("%d
    ",ans[i]);
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
    

    B. CQOI2015 选数

    Descripion

    [sum_{a_1=L}^R sum_{a_2=L}^Rdotssum_{a_n=L}^R [gcd(a_1,a_2,a_3,dots,a_n)=k] (mod 10^9+7) ]

    所有参量满足 (le 10^9)

    Solution

    式子真难看,反手一推变成

    [sum_{i=1}^{lfloor frac R k floor} mu(i) (lfloor frac {lfloor frac R k floor} i floor-frac {lfloor frac L k floor} i floor)^n ]

    (考试的时候推错式子了……然后外加一些手残就爆零了)

    其实搞几个变量代替一下就没这么麻烦了……

    然后我们发现这种做法需要开不下的空间做 (mu)

    然后去学了一下杜教筛就做完了

    或者容斥大佬会这种做法

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define inf (int)1e18+10
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int mod=1e9+7;
    	inline int ksm(int x,int y)
    	{
    		int res=1; 
    		for(;y;y>>=1,x=x*x%mod) if(y&1) res=res*x%mod;
    		return res;
    	}
    	inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    	const int N=7e6+10;
    	bool fl[N];
    	int pri[N],cnt,mu[N],n,l,h,k,ans,low,up;
    	inline void prework()
    	{
    		mu[1]=1;
    		for(int i=2;i<N;++i) 
    		{
    			if(!fl[i]) pri[++cnt]=i,mu[i]=mod-1;
    			for(int j=1;j<=cnt&&i*pri[j]<N;++j) 
    			{
    				fl[i*pri[j]]=1;
    				if(i%pri[j]==0){mu[i*pri[j]]=0; break;}
    				else mu[i*pri[j]]=-mu[i],mu[i*pri[j]]=(mu[i*pri[j]]+mod)%mod;
    			}
    		} 
    		for(int i=1;i<N;++i) mu[i]=add(mu[i],mu[i-1]);
    		return ;
    	}
    	map<int,int> mp;
    	inline void calc(int x,int &ans)
    	{
    		if(x<N) return ans=mu[x],void();
    		if(mp[x]) return ans=mp[x],void();
    		ans=1; 
    		for(int l=2,r,s=0;l<=x;l=r+1)
    		{
    			r=x/(x/l); s=0;
    			calc(x/l,s);
    			(s+=mod)%mod;
    			ans-=(r-l+1)*s%mod; 
    			ans=add(ans,mod);
    		} return mp[x]=ans,void();
    	}
    	inline int ask(int x)
    	{
    		int ans=0; calc(x,ans); return ans;
    	}
    	signed main()
    	{
    		n=read(); k=read(); l=read(); h=read();
    		low=(l-1)/k; up=h/k;
    		if(low>up) return puts("0"),0;
    		prework(); 
    		for(int i=1,j;i<=up;i=j+1)
    		{
    			j=min(low/i?low/(low/i):inf,up/(up/i));
    			ans=add(ans,(ask(j)-ask(i-1)+mod)%mod*ksm(up/i-low/i,n)%mod);
    		} cout<<ans<<endl;
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    

    C.树点涂色

    (sb) 的一个题目了,不到二十天之前刚刚做完,然后今天就忘记了

    不写了,直接贴link

    总结

    感觉上午状态很诡异,上手记错了一个结论,线段树写了一个多小时,还妄想自己能 (AK) 结果呢?

    (20)

    好好的 (lct) 不会打,反演的式子还推错

    我服了我自己,慢慢考试慢慢进步吧

  • 相关阅读:
    hdu 1823 Luck and Love 二维线段树
    UVA 12299 RMQ with Shifts 线段树
    HDU 4578 Transformation 线段树
    FZU 2105 Digits Count 线段树
    UVA 1513 Movie collection 树状数组
    UVA 1292 Strategic game 树形DP
    【ACM】hdu_zs2_1003_Problem C_201308031012
    qsort快速排序
    【ACM】nyoj_7_街区最短路径问题_201308051737
    【ACM】nyoj_540_奇怪的排序_201308050951
  • 原文地址:https://www.cnblogs.com/yspm/p/13373158.html
Copyright © 2011-2022 走看看