zoukankan      html  css  js  c++  java
  • 联考20200612 T2 「雅礼集训 2018 Day11」字符串

    题目传送门

    分析:
    集合G的成功的答案不好算,我们可以用1减去失败的概率,失败的的情况只可能是随机区间在G相邻两个元素之间
    我们考虑集合删除,最暴力的就是使用Set直接删除
    单次删除(O(logn))不优,这道题维护信息只考虑删除的话可以使用双向链表
    但是插入就麻烦了,我们不知道当前插入的关键点在哪里,需要二分,怎么做到(O(1))
    我们先把所有的字符串放进去检验,可以把Trie上的所有点的(f)求出来,并求出集合(G)
    这样所有的关键点都求了出来,我们就可以保存好关键点(O(1))插入了
    可以使用莫队,但是链表插入时,插入的顺序必须严格对应之前删除的顺序,否则双向链表就会出现错误
    于是使用黑科技:回滚莫队,不会的童鞋可以看看这篇博客
    然后直接维护就好了

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<queue>
    #include<map>
    
    #define maxn 300005
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    inline int getint()
    {
    	int num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n,A,B,C,L,S,Q;
    struct node{
    	int l,r,id;
    }q[maxn];
    char s[maxn];
    int val[maxn],len[maxn],bl[maxn],g[maxn];
    int ch[maxn][26],dpt[maxn],cur;
    int p[maxn],tot,pos[maxn],v[maxn],b[maxn];
    int stk[maxn],tp;
    int l[maxn],r[maxn];
    long long F[maxn],ans[maxn];
    long long Sum,Now;
    inline bool cmp(node x,node y){return bl[x.l]==bl[y.l]?x.r>y.r:x.l<y.l;}
    
    inline void insert(int x)
    {
    	int now=0;
    	for(int i=1;i<=len[x];i++)
    	{
    		int c=s[i]-'a';
    		if(!ch[now][c])ch[now][c]=++cur,dpt[cur]=dpt[now]+1;
    		now=ch[now][c],pos[++tot]=now,v[tot]=val[x];
    	}
    }
    inline long long cal(long long x)
    {return x*(x+1)/2;}
    inline long long gcd(long long p,long long q)
    {return q?gcd(q,p%q):p;}
    
    inline bool check(long long X,long long Y)
    {return X?B*X+Y*A>=C:0;}
    inline void add(int i)
    {
    	int x=pos[i];
    	if(!check(F[x],dpt[x])&&check(F[x]+v[i],dpt[x])&&!(b[g[dpt[x]]]++))
    	{
    		int k=g[dpt[x]],ll=l[k],rr=r[k];
    		r[ll]=k,l[rr]=k,Now+=cal(rr-ll-1),Now-=cal(k-ll-1),Now-=cal(rr-k-1);
    	}
    	F[x]+=v[i];
    }
    inline void del(int i)
    {
    	int x=pos[i];
    	if(check(F[x],dpt[x])&&!check(F[x]-v[i],dpt[x])&&!(--b[g[dpt[x]]]))
    	{
    		int k=g[dpt[x]],ll=l[k],rr=r[k];
    		r[ll]=rr,l[rr]=ll,Now-=cal(rr-ll-1),Now+=cal(k-ll-1),Now+=cal(rr-k-1);
    	}
    	F[x]-=v[i];
    }
    
    int main()
    {
    	n=getint(),A=getint(),B=getint(),C=getint();
    	for(int i=1;i<=n;i++)val[i]=getint();
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",s+1),L=max(L,len[i]=strlen(s+1));
    		insert(i),len[i]+=len[i-1];
    	}
    	S=sqrt(tot);
    	for(int i=1;i<=tot;i++)bl[i]=(i-1)/S+1;
    	for(int i=1;i<=L;i++)g[i]=getint();
    	Q=getint();
    	Now=Sum=cal(L);
    	for(int i=1;i<=Q;i++)
    		q[i].l=len[getint()-1]+1,q[i].r=len[getint()],q[i].id=i;
    	sort(q+1,q+Q+1,cmp);
    	for(int i=1,x=pos[i];i<=tot;i++,x=pos[i])
    	{
    		if(!check(F[x],dpt[x])&&check(F[x]+v[i],dpt[x])&&!(b[g[dpt[x]]]++))
    			stk[++tp]=g[dpt[x]];
    		F[x]+=v[i];
    	}
    	stk[++tp]=0,stk[++tp]=L+1;sort(stk+1,stk+tp+1);
    	for(int i=1;i<=tp;i++)l[stk[i]]=stk[i-1],r[stk[i]]=stk[i+1];
    	for(int i=2;i<=tp;i++)Now-=cal(stk[i]-stk[i-1]-1);
    	for(int i=1,j=S,now=1,l=i,r=tot;i<=tot&&now<=Q;i+=S,j+=S)
    	{
    		while(now<=Q&&q[now].l>=i&&q[now].l<=j)
    		{
    			while(r>q[now].r)del(r--);while(l<q[now].l)del(l++);
    			ans[q[now].id]=Now;while(l>i)add(--l);now++;
    		}
    		while(r<tot)add(++r);while(l<=j)del(l++);
    	}
    	for(int i=1;i<=Q;i++)
    	{
    		long long tmp=gcd(ans[i],Sum);
    		printf("%lld/%lld
    ",ans[i]/tmp,Sum/tmp);
    	}
    }
    

  • 相关阅读:
    php 基础------数组过滤
    js或者jq 使用cookie 时在谷歌浏览器不好使
    css3 -阻止元素成为鼠标事件目标 pointer-events
    CSS3-----transform 转换
    css3---过渡
    css3动画----animation
    移动端尺寸适配--媒体查询
    工作一年总结
    关于Jquery.Data()和HTML标签的data-*属性
    android shape
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13110615.html
Copyright © 2011-2022 走看看