zoukankan      html  css  js  c++  java
  • hdu 6096 String

      OvO http://acm.hdu.edu.cn/showproblem.php?pid=6096

      ( 2017 Multi-University Training Contest - Team 6 - 1001)

      对于n个串,构造新串。(构造方法:例如若串为ABCDE,构造新串为AEBDCCDBEA)、

      将新串插入到字典树(字典树每个节点存放一个vector)中,对于每个新串遍历到的节点,将原串的长度长度放入这些节点的vector中、

      将字典树每个节点的vector从小到大排序。

      对于询问的前后缀,类似地构造新串,空余出补*,(例如前缀ABC,后缀DEFGH,构造新串为AHBGCF*E*D)

      然后对于这些新串在字典树中进行询问,对于每个匹配到的节点,合法串的数量就是vector中保存的长度大于等于前缀后缀长度和的数字的数量。

      (思路来源于某大佬

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    const int M=5e5+44;
    const int N=1e5+44;
    
    struct Node
    {
    	int len,pos;
    };
    
    queue<Node> que;
    
    struct Trie
    {
    	const static int TRIE_M=1204000;
    	const static int CHAR_SIZE=26;
    	
    	int root,tol,ch[TRIE_M][27];
    	vector<int> tree[TRIE_M];
    	
    	int newnode()
    	{
    		tree[tol].clear();
    		for(int i=0;i<26;i++)
    			ch[tol][i]=-1;
    		return tol++;
    	}
    	
    	void init()
    	{
    		tol=0;
    		root=newnode();
    	}
    	
    	void insert(char strtmp[],int lentmp)
    	{
    //		cout<<"strtmp: "<<strtmp<<endl;
    		int i,j;
    		int now=root,nxt,valtmp;
    		for(i=0;i<lentmp;i++)
    		{
    			valtmp=strtmp[i]-'a';
    			if(ch[now][valtmp]==-1)
    				ch[now][valtmp]=newnode(); 
    			now=ch[now][valtmp];
    			tree[now].push_back(lentmp/2);
    //			cout<<"now: "<<now<<"  tree[now] size: "<<tree[now].size()<<endl;
    		}
    	}
    	
    	void build()
    	{
    		for(int i=0;i<tol;i++)
    			sort(tree[i].begin(),tree[i].end());
    	}
    	
    	int getval(int pos,int xlen)
    	{
    		int li=-1,ri=tree[pos].size(),mid;
    //		cout<<"getval pos:"<<pos<<' '<<" size: "<<tree[pos].size()<<endl;
    //		cout<<"detail val:"<<tree[pos][0]<<' '<<tree[pos][1]<<endl;
    		while(li<ri-1)
    		{
    			mid=(li+ri)>>1;
    			if(tree[pos][mid]<xlen)
    				li=mid;
    			else ri=mid;
    		}
    //		cout<<"li: "<<li<<endl;
    		return tree[pos].size()-(li+1);
    	}
    	
    	int query(char strtmp[],int lentmp,int xlen)
    	{
    		char chrtmp;
    		int i,j,ret=0,pos,nxt;
    		Node q,qq;
    		while(!que.empty())
    			que.pop();
    		q.len=0; q.pos=0;
    		que.push(q);
    		while(!que.empty())
    		{
    			q=que.front(); que.pop();
    			chrtmp=strtmp[q.len];
    			pos=q.pos;
    //			cout<<chrtmp<<' '<<pos;
    //			if(chrtmp!='*')
    //				cout<<"  ch[pos][chrtmp-'a']= "<<ch[pos][chrtmp-'a'];
    //			cout<<endl;
    			if(chrtmp=='*')
    				for(i=0;i<26;i++)
    				{
    					nxt=ch[pos][i];
    					if(nxt!=-1)
    					{
    						qq.len=q.len+1;
    						qq.pos=nxt;
    						if(qq.len==lentmp)
    							ret+=getval(qq.pos,xlen);
    						else que.push(qq);
    					}
    				}
    			else
    			{
    				nxt=ch[pos][chrtmp-'a'];
    				if(nxt!=-1)
    				{
    					qq.len=q.len+1;
    					qq.pos=nxt;
    					if(qq.len==lentmp)
    						ret+=getval(qq.pos,xlen);
    					else que.push(qq);
    				}
    			}	
    		}
    		return ret;
    	}
    } trie;
    
    int n,q;
    char strtmp[M],pretmp[M],suftmp[M],strget[M];
    
    int main()
    {
    //	freopen("数据\1001.in","r",stdin);
    //	freopen("数据\fxxl1001.out","w",stdout);
    	int lentmp,prelen,suflen;
    	int cas,i,j,ans;
    	scanf("%d",&cas);
    	while(cas--)
    	{
    		scanf("%d%d",&n,&q);
    		trie.init();
    		for(i=1;i<=n;i++)
    		{
    			scanf("%s",strtmp);
    			lentmp=strlen(strtmp);
    			for(j=0;j<lentmp;j++)
    			{
    				strget[j*2]=strtmp[j];
    				strget[j*2+1]=strtmp[lentmp-1-j];
    			}
    			trie.insert(strget,lentmp*2);
    		}
    		trie.build();
    		for(i=1;i<=q;i++)
    		{
    			scanf("%s%s",pretmp,suftmp);
    			reverse(suftmp,suftmp+strlen(suftmp));
    			prelen=strlen(pretmp); suflen=strlen(suftmp);
    			lentmp=max(prelen,suflen);
    			for(j=0;j<lentmp;j++)
    			{
    				if(j<prelen)
    					strget[j*2]=pretmp[j];
    				else strget[j*2]='*';
    				if(j<suflen)
    					strget[j*2+1]=suftmp[j];
    				else strget[j*2+1]='*';
    			}
    			lentmp*=2;
    			if(strget[lentmp-1]=='*') lentmp--;
    			ans=trie.query(strget,lentmp,prelen+suflen);
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    
    /*
    
    1
    4 1
    aaaa
    aaaaa
    aaaaa
    aa
    aa aa
    
    */
    

      

  • 相关阅读:
    iOS上传AppStore被拒原因及处理方案
    记录一个打包upload时报错处理
    Git撤销merge
    设置UIButton上面是image,下面是title
    Sourcetree中切换到其他分支,临时分支的这次提交丢失
    修改字符串指定范围的颜色
    定时消失的Alert弹窗
    ALAsset 将资源转换为 NSData
    textField和textView的输入字数最大限制
    手机号码正则判断
  • 原文地址:https://www.cnblogs.com/FxxL/p/7346306.html
Copyright © 2011-2022 走看看