之前立下了一个flag,每个有空的下午做一套CF来增长智商。
G. Symmetree
问题的本质如何快速比对两个子树是否相同。
考虑树hash。这里采用的是主流的AHU算法(安徽大学(不是)
主要将vector排序后放map里来获取hash值。
即vector就是一个键值。由于每个点只在父亲处贡献每个父亲只访问一次总复杂度是nlog的。
这样的hash显然是准确的。
code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define inf 10000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define putl_(x) printf("%lld ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define l(w) t[w].l
#define r(w) t[w].r
#define L(w) s[w].l
#define R(w) s[w].r
#define yy p<<1|1
#define zz p<<1
#define sum(w) t[w].sum
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define sub(x,y) (x-y<0?x-y+mod:x-y)
using namespace std;
const int MAXN=2000010,N=888,G=3;
int T,n,id,top,len;
int has[MAXN],ans[MAXN],s[MAXN];
int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
vector<int>g[MAXN];
map<vector<int>,int>H;
inline void add(int x,int y)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
}
inline void dfs(int x,int fa)
{
g[x].clear();
go(x)
{
if(tn==fa)continue;
dfs(tn,x);
g[x].pb(has[tn]);
}
sort(g[x].begin(),g[x].end());
if(H.find(g[x])!=H.end())has[x]=H[g[x]];
else H[g[x]]=++id,has[x]=id;
top=0;
rep(0,(int)g[x].size()-1,j)
{
if(top&&s[top]==g[x][j])--top;
else s[++top]=g[x][j];
}
if(top>=2)ans[x]=-1;
if(top==0)ans[x]=1;
if(top==1)go(x)if(tn!=fa&&has[tn]==s[top])
{
ans[x]=ans[tn];
break;
}
}
int main()
{
freopen("1.in","r",stdin);
sc(T);
while(T--)
{
sc(n);H.clear();
len=0;id=0;
rep(1,n,i)
{
lin[i]=0;
}
rep(2,n,i)
{
int x,y;
sc(x);
sc(y);
add(x,y);add(y,x);
}
dfs(1,0);
puts(ans[1]==1?"YES":"NO");
}
return 0;
}
仔细分析题目所给条件只需满足最后两个条件即可。
可以枚举某个字母是否出现,这样变成了两个串异或为全1的情况。
使用map来数点即可。
注意在查找是要先find一下避免增加不必要的键值,不然直接跑回超时。
code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define inf 10000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define putl_(x) printf("%lld ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define l(w) t[w].l
#define r(w) t[w].r
#define L(w) s[w].l
#define R(w) s[w].r
#define yy p<<1|1
#define zz p<<1
#define sum(w) t[w].sum
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define sub(x,y) (x-y<0?x-y+mod:x-y)
using namespace std;
const int MAXN=5000010,N=888,G=3;
int T,n,id,top,len;
char a[MAXN];
int w[MAXN];
map<int,int>H[26];
int main()
{
//freopen("1.in","r",stdin);
sc(n);
int maxx=(1<<26)-1;
ll ans=0;
//int last=0;
rep(1,n,i)
{
scs(a+1);
int m=strlen(a+1);
rep(1,m,j)
{
int x=a[j]-'a';
++w[x];
}
int v=0,ww;
for(int k=25;k>=0;--k)v=v<<1|(w[k]&1);
rep(0,25,k)
{
if(!w[k])
{
ww=maxx^(1<<k);
ww=ww^v;
if(H[k].find(ww)!=H[k].end())ans+=H[k][ww];
++H[k][v];
}
w[k]=0;
}
//cout<<(last^v)<<' '<<(maxx^(1<<25))<<endl;
}
putl(ans);
return 0;
}
E 两个版本几乎相同。
仔细思考发现有一段区间的点可以任意交换。
还有一段连续区间不能交换。分别做判断就行。
有手就行。
code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define inf 10000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define putl_(x) printf("%lld ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define l(w) t[w].l
#define r(w) t[w].r
#define L(w) s[w].l
#define R(w) s[w].r
#define yy p<<1|1
#define zz p<<1
#define sum(w) t[w].sum
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define sub(x,y) (x-y<0?x-y+mod:x-y)
using namespace std;
const int MAXN=5000010,N=888,G=3;
int T,n,k,id,top,len;
char a[MAXN],b[MAXN];
int w[MAXN];
map<int,int>H[26];
int main()
{
//freopen("1.in","r",stdin);
sc(T);
while(T--)
{
sc(n);sc(k);
scs(a+1);
scs(b+1);
int flag=0;
if(k>=n)
{
rep(1,n,i)if(a[i]!=b[i])flag=1;
if(flag)puts("NO");
else puts("YES");
continue;
}
int cc=n-k+1;
if(cc<=k)
{
rep(cc,k,i)if(a[i]!=b[i])flag=1;
rep(1,cc-1,i)++w[a[i]-'a'],--w[b[i]-'a'];
rep(k+1,n,i)++w[a[i]-'a'],--w[b[i]-'a'];
}
else rep(1,n,i)++w[a[i]-'a'],--w[b[i]-'a'];
rep(0,25,i)
{
if(w[i])flag=1;
w[i]=0;
}
if(flag)puts("NO");
else puts("YES");
}
return 0;
}
既然E题有手就行其他题就不做了,下班。
标签:855,int,top,Codeforces,long,printf,Div,include,define From: https://www.cnblogs.com/chdy/p/17219108.html