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);
    	}
    }
    

  • 相关阅读:
    Postman使用教程
    CAD和ArcGIS转换 矢量配准
    SAP CRM Advanced search和Simple search里Max hit表现行为的差异
    SAP CRM Product simple search的启用步骤
    如何快速定位SAP CRM订单应用(Order Application)错误消息抛出的准确位置
    如何动态修改SAP CRM WebClient UI表格栏的宽度
    如何在SAP CRM WebClient UI里创建web service并使用ABAP消费
    如何处理SAP CRM Web Service错误
    如何使用SAP CRM WebClient UI实现一个类似新浪微博的字数统计器
    如何开启SAP CRM基于WORD模板创建附件的功能
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13110615.html
Copyright © 2011-2022 走看看