# 6.25联考题解

A：

$f\left[a\right]\left[b\right]$$f[a][b]$表示集合中前8位的数是$a$$a$的数里，和一个后8位是$b$$b$的数做位运算，后8位结果的最大值
$x$$x$的前8位是$x$$x$，后8位是$y$$y$

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 210000;
const int maxb = 256;

int n,opt,type;
int f[maxb][maxb],g[maxb][maxb];

char str[110];
int main()
{
freopen("binary.in","r",stdin);
freopen("binary.out","w",stdout);

scanf("%d%s%d",&n,str,&type);
opt=str[0]=='a'?0:(str[0]=='o'?1:2);

for(int i=1;i<=n;i++)
{
int x; scanf("%d",&x); int y=x&255; x^=y;
if(i>1)
{
int nowmax=0,nowsum=0;
for(int j=0;j<maxb;j++)
{
int cx=f[j][y],cs=g[j][y];
if(!cs) continue;
int cj=j<<8;
cx|=opt==0?(cj&x):(opt==1?(cj|x):(cj^x));
if(cx>nowmax) nowmax=cx,nowsum=0;
if(cx==nowmax) nowsum+=cs;
}
if(type) printf("%d %d\n",nowmax,nowsum);
else printf("%d\n",nowmax);
}

x>>=8;
for(int j=0;j<maxb;j++)
{
int cx=opt==0?(y&j):(opt==1?(y|j):(y^j));
if(f[x][j]<cx) f[x][j]=cx,g[x][j]=0;
if(f[x][j]==cx) g[x][j]++;
}
}

return 0;
}


B：

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 610000;
const int maxp = maxn*25;

int n,m,type;
struct segment
{
int cnt;
int seg[maxp],lc[maxp],rc[maxp];
int loc,c;
int newnode(int x)
{
++cnt;
lc[cnt]=lc[x],rc[cnt]=rc[x];
seg[cnt]=seg[x];
return cnt;
}
void upd(int &x,const int l,const int r)
{
x=newnode(x);
if(l==r){ seg[x]=c;return; }
int mid=(l+r)>>1;
loc<=mid?upd(lc[x],l,mid):upd(rc[x],mid+1,r);
}
int q(int x,const int l,const int r)
{
if(l==r) return seg[x];
int mid=(l+r)>>1;
return loc<=mid?q(lc[x],l,mid):q(rc[x],mid+1,r);
}
}Son,P;
int tot,fl[maxn],len[maxn],rootp[maxn],rootson[maxn];
int stri[maxn];
int ans;

{
x=stri[x];
int now=++tot; stri[i]=now;
len[now]=len[x]+1;

int y=++tot; fl[y]=fl[x],len[y]=len[x],rootp[y]=rootp[x],rootson[y]=rootson[x];
P.loc=len[y],P.c=y,P.upd(rootp[y],0,n);

P.loc=fl[y]; int tmp=P.q(rootp[y],0,n);
Son.loc=c; tmp=Son.q(rootson[tmp],1,m);
P.loc=tmp; tmp=P.q(rootp[y],0,n);

Son.loc=c,Son.c=len[now],Son.upd(rootson[y],1,m);

fl[now]=len[tmp];
rootp[now]=rootp[y];
P.loc=len[now],P.c=now,P.upd(rootp[now],0,n);
rootson[now]=rootson[tmp];

//P.loc=0,printf("%d\n",P.q(rootp[now],0,n));
//Son.loc=1; int temp=Son.q(rootson[now],1,m);
//int ii=1;
}

int main()
{
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);

for(int i=1;i<=n;i++)
{
x^=ans,c^=ans;

printf("%d\n",ans=(len[stri[i]]-fl[stri[i]]));
ans*=type;
}

return 0;
}


C：

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define pb push_back
#define SZ(x) (int)x.size()
using namespace std;

{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
inline void up(int &a,const int &b){if(a<b)a=b;}
const int maxn = 210000;
const double pi = acos(-1);

namespace FFT
{
struct E
{
double x,y;
friend inline E operator +(const E &x,const E &y){return (E){x.x+y.x,x.y+y.y};}
friend inline E operator -(const E &x,const E &y){return (E){x.x-y.x,x.y-y.y};}
friend inline E operator *(const E &x,const E &y){return (E){x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x};}
}s1[maxn],s2[maxn];
int N,id[maxn],ln;
void dft(E f[],int sig)
{
for(int i=0;i<N;i++) if(i<id[i]) swap(f[i],f[id[i]]);
for(int m=2;m<=N;m<<=1)
{
int t=m>>1;
E w=(E){cos(2*pi/m),sin(2*pi*sig/m)};
for(int j=0;j<N;j+=m)
{
E wn=(E){1,0};
for(int i=0;i<t;i++)
{
E tx=f[j+i],ty=f[j+i+t]*wn;
f[j+i]=tx+ty;
f[j+i+t]=tx-ty;
wn=wn*w;
}
}
}
if(sig==-1)
{
for(int i=0;i<N;i++) f[i].x/=(double)N;
}
}
void solve(int f[],int g[],int fn,int gn)
{
N=1,ln=0;
while(N<=fn+gn) N<<=1,ln++;
for(int i=1;i<N;i++) id[i]=id[i>>1]>>1|(i&1)<<(ln-1);

for(int i=0;i<=fn;i++) s1[i]=(E){(double)f[i],0};
for(int i=fn+1;i<N;i++) s1[i]=(E){0,0};

for(int i=0;i<=gn;i++) s2[i]=(E){(double)g[i],0};
for(int i=gn+1;i<N;i++) s2[i]=(E){0,0};

dft(s1,1); dft(s2,1);
for(int i=0;i<N;i++) s1[i]=s1[i]*s2[i];
dft(s1,-1);

for(int i=0;i<N;i++) f[i]=(int)(s1[i].x+0.5);
}
}

int n,m;
int c[maxn];
ll ans[maxn];
struct edge{int y,nex;}a[maxn<<1]; int len,fir[maxn],v[maxn];
inline void ins(const int x,const int y){a[++len]=(edge){y,fir[x]};fir[x]=len;}

int siz[maxn];
int findrt(int x,int fa,int N)
{
siz[x]=1; int mxs=0;
for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(!v[k]&&y!=fa)
{
int re=findrt(y,x,N); if(re) return re;
siz[x]+=siz[y];
up(mxs,siz[y]);
}
if(mxs*2<=N&&(N-siz[x])*2<=N) return x;
return 0;
}
vector<int>Vl[maxn],Vr[maxn];
int lx,rx;
void dfsl(int x,int fa,int sum,int mx,int now)
{
siz[x]=1;

sum+=c[x]; up(lx,sum);
if(sum>mx) mx=sum,now=-1;
if(sum==mx) Vl[sum].pb(++now);

for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(y!=fa&&!v[k])
dfsl(y,x,sum,mx,now),siz[x]+=siz[y];
}
void dfsr(int x,int fa,int sum,int mn,int now)
{
sum+=c[x]; up(rx,-sum);
if(sum<mn) mn=sum,now=-1;
if(sum==mn) Vr[-sum].pb(++now);

for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(y!=fa&&!v[k])
dfsr(y,x,sum,mn,now);
}
int f[maxn],g[maxn],fn,gn;
void calc(int sig)
{
for(int i=0,ui=min(lx,rx);i<=ui;i++)
{
for(int j=0;j<=fn+gn;j++) f[j]=g[j]=0;
fn=gn=0;

for(int j=0;j<SZ(Vl[i]);j++)
{
int x=Vl[i][j];
f[x]++; up(fn,x);
}
for(int j=0;j<SZ(Vr[i]);j++)
{
int x=Vr[i][j];
g[x]++; up(gn,x);
}
FFT::solve(f,g,fn,gn);
for(int j=0;j<=fn+gn;j++) ans[j+(i>0)]+=f[j]*sig;
}
}
void Divide_And_Conquer(int x,int N)
{
x=findrt(x,0,N);
while(lx>=0) Vl[lx--].clear();
while(rx>=0) Vr[rx--].clear();
dfsl(x,0,0,0,0);
Vr[rx=0].pb(0);
for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(!v[k])
dfsr(y,x,0,0,0);
calc(1);

for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(!v[k])
{
while(lx>=0) Vl[lx--].clear();
while(rx>=0) Vr[rx--].clear();
dfsl(y,x,c[x],max(c[x],0),0);
dfsr(y,x,0,0,0);
calc(-1);
}
for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(!v[k])
{
v[k]=v[k^1]=1;
Divide_And_Conquer(y,siz[y]);
}
}

char str[110];
int main()
{
freopen("inverse.in","r",stdin);
freopen("inverse.out","w",stdout);

len=1;

for(int i=1;i<n;i++)
{
ins(x,y),ins(y,x);
}
for(int i=1;i<=n;i++)
{
scanf("%s",str);
c[i]=str[0]=='('?1:-1;
}

Divide_And_Conquer(1,n);

while(m--)
{