zoukankan      html  css  js  c++  java
  • 【HDU5469】Antonidas(点分治,字符串哈希)

    【HDU5469】Antonidas(点分治,字符串哈希)

    题面

    HDU
    Vjudge

    题解

    啊哈?什么垃圾一眼点分治+Hash判断,哈哈哈哈哈,让我来码码码。
    诶,怎么WA了。改改改改改。
    诶,怎么很对啊,去网上蒯一个标程来拍拍拍。
    诶,怎么拍不WA啊,让我来人工检测一波啊哈哈哈哈。
    感觉没有问题啊?诶,我换个方式来拍把,把字符集设小点就好了。
    诶,WA不了,诶诶诶诶,WA了。
    WOC,数据1w让我怎么手玩。
    不管了,先把剪枝删掉再试试,诶诶诶,怎么答案对了?
    我之前交不加剪枝的不是TLE了吗?
    诶诶诶,WOC,怎么过了,哈哈哈哈哈,果然是傻逼点分治+Hash题。
    诶,怎么,,,,怎么我的晚自习就没了呢?我怎么哭了?诶诶诶诶?

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<set>
    using namespace std;
    #define MAX 10010
    #define ull unsigned long long
    const int base=19260817;
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    struct Line{int v,next;}e[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
    int n;
    int size[MAX],Size,mx,root;
    bool vis[MAX];
    void getroot(int u,int ff)
    {
    	size[u]=1;int ret=0;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;if(v==ff||vis[v])continue;
    		getroot(v,u);size[u]+=size[v];
    		ret=max(ret,size[v]);
    	}
    	ret=max(ret,Size-size[u]);
    	if(ret<mx)mx=ret,root=u;
    }
    int len;
    char ch[MAX],s[MAX];
    ull hs[MAX],pw[MAX];
    set<int> S1,S2;
    bool ans;
    ull get(int l,int r){return hs[r]-hs[l-1]*pw[r-l+1];}
    void calc(int u,int ff,int dep,ull h1,ull h2)
    {
    	if(ans)return;if(dep>=len)return;
    	h1=h1*base+ch[u];h2=h2+pw[dep]*ch[u];
    	if(dep+1==len&&h1==get(1,len)){ans=true;return;}
    	if(h1==get(len-dep,len)&&S2.count(len-dep-1)){ans=true;return;}
    	if(h2==get(1,dep+1)&&S1.count(dep+2)){ans=true;return;}
    	for(int i=h[u];i;i=e[i].next)
    		if(!vis[e[i].v]&&e[i].v!=ff)
    			calc(e[i].v,u,dep+1,h1,h2);
    }
    void insert(int u,int ff,int dep,ull h1,ull h2)
    {
    	if(ans)return;if(dep>=len)return;
    	h1=h1*base+ch[u];h2=h2+pw[dep]*ch[u];
    	if(h1==get(len-dep,len))S1.insert(len-dep);
    	if(h2==get(1,dep+1))S2.insert(dep+1);
    	for(int i=h[u];i;i=e[i].next)
    		if(!vis[e[i].v]&&e[i].v!=ff)
    			insert(e[i].v,u,dep+1,h1,h2);
    }
    void Divide(int u)
    {
    	if(ans)return;vis[u]=true;
    	S1.clear();S2.clear();
    	if(ch[u]==s[1])S2.insert(1);
    	if(ch[u]==s[len])S1.insert(len);
    	if(len==1&&ch[u]==s[1]){ans=true;return;}
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;if(vis[v])continue;
    		calc(v,u,0,0,0);insert(v,u,1,ch[u],ch[u]);
    	}
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;if(vis[v])continue;
    		Size=mx=size[v];getroot(v,u);
    		Divide(root);
    	}
    }
    int main()
    {
    	pw[0]=1;for(int i=1;i<MAX;++i)pw[i]=pw[i-1]*base;
    	int T=read();
    	for(int TT=1;TT<=T;++TT)
    	{
    		n=read();cnt=1;memset(h,0,sizeof(h));
    		memset(vis,0,sizeof(vis));
    		for(int i=1;i<n;++i)
    		{
    			int u=read(),v=read();
    			Add(u,v);Add(v,u);
    		}
    		scanf("%s",ch+1);scanf("%s",s+1);len=strlen(s+1);
    		memset(hs,0,sizeof(hs));
    		for(int i=1;i<=len;++i)hs[i]=hs[i-1]*base+s[i];
    		ans=false;Size=mx=n;getroot(1,0);
    		Divide(root);
    		printf("Case #%d: ",TT);
    		ans?puts("Find"):puts("Impossible");
    	}
    	return 0;
    }
    	
    
  • 相关阅读:
    CSS学习笔记(二)选择器
    CSS学习笔记(九)对列表应用样式和创建导航条
    在Eclipse中用远程svn资源库创建项目并提交和更新
    CSS学习笔记(六)圆角框
    CSS学习笔记(五)背景图基础
    SVN创建资源库和远程连接配置
    Struts2标签中支持OGNL表达式的热计算及带参数的<s:a>链接
    php处理字符串格式的计算公式
    CSS学习笔记(十)对表单和数据表格使用样式
    CSS学习笔记(三)层叠和特殊性
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9665368.html
Copyright © 2011-2022 走看看