BZOJ3879 SvT

来源:互联网 发布:企业大数据战略 编辑:程序博客网 时间:2024/06/05 16:43

Orz PoPoQQQ 大爷

造个后缀树,跑虚树,很裸的题

模数过大需要快速乘,每次被乘数*2,乘数如果这位是1则把答案加上当前被乘数

不过discuss说不模也行?

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<algorithm>#include<iomanip>#include<vector>#include<stack>#include<queue>#include<set>#include<bitset>#include<map>using namespace std;#define MAXN 1000010#define MAXM 1010#define ll long long#define eps 1e-8#define INF 1000000000#define MOD 23333333333333333llstruct vec{int to;int fro;};struct G{vec mp[MAXN];int tai[MAXN],cnt;inline void be(int x,int y){if(x==y){return ;}mp[++cnt].to=y;mp[cnt].fro=tai[x];tai[x]=cnt;}void pre(int x);void dp(int x,int f);};G tr,nt;int fa[MAXN],son[MAXN][26],mx[MAXN];int rt,lst,tot;int n,m;char s[MAXN];int pos[MAXN],dfn[MAXN],tim;int Fa[MAXN][25],dep[MAXN];int st[MAXN],tp;int t[MAXN];int siz[MAXN];int v[MAXN];int T;ll ans;bool cmp(int x,int y){return dfn[x]<dfn[y];}void G::pre(int x){int i,j,y,t;dfn[x]=++tim;dep[x]=dep[Fa[x][1]]+1;for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;for(t=x,j=1;t;j++){Fa[y][j]=t;t=Fa[t][j];}pre(y);}}ll mul(ll x,ll y){ll re=0;while(y){if(y&1){(re+=x)%=MOD;}(x*=2)%=MOD;y>>=1;}return re;}void G::dp(int x,int f){int i,y;if(v[x]==T){siz[x]=1;}else{siz[x]=0;}for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;dp(y,x);siz[x]+=siz[y];}if(siz[x]&1){(ans+=mul(mul((siz[x]-1)/2,siz[x]),(mx[x]-mx[f])))%=MOD;}else{(ans+=mul(mul((siz[x]-1),siz[x]/2),(mx[x]-mx[f])))%=MOD;}tai[x]=0;}int lca(int x,int y){int i;if(dep[x]<dep[y]){swap(x,y);}for(i=24;i;i--){if(dep[Fa[x][i]]>=dep[y]){x=Fa[x][i];}}for(i=24;i;i--){if(Fa[x][i]!=Fa[y][i]){x=Fa[x][i];y=Fa[y][i];}}return x==y?x:Fa[x][1];}void ins(int x){int np=++tot,p=lst;mx[np]=mx[p]+1;while(p&&!son[p][x]){son[p][x]=np;p=fa[p];}if(!p){fa[np]=rt;}else{int q=son[p][x];if(mx[q]==mx[p]+1){fa[np]=q;}else{int nq=++tot;mx[nq]=mx[p]+1;memcpy(son[nq],son[q],sizeof(son[q]));fa[nq]=fa[q];fa[np]=fa[q]=nq;while(p&&son[p][x]==q){son[p][x]=nq;p=fa[p];}}}lst=np;}int main(){//freopen("data.txt","r",stdin);//freopen("dui.txt","w",stdout);int i;rt=lst=tot=1;scanf("%d%d",&n,&m);scanf("%s",s+1);for(i=n;i;i--){ins(s[i]-'a');pos[i]=lst;}for(i=2;i<=tot;i++){tr.be(fa[i],i);}tr.pre(1);while(m--){scanf("%d",&n);nt.cnt=0;T++;for(i=1;i<=n;i++){scanf("%d",&t[i]);t[i]=pos[t[i]];v[t[i]]=T;}sort(t+1,t+n+1,cmp);st[tp=1]=1;for(i=1;i<=n;i++){int l=lca(t[i],st[tp]);while(dep[st[tp]]>dep[l]){if(dep[st[tp-1]]>=dep[l]){nt.be(st[tp],st[tp--]);}else{nt.be(l,st[tp--]);}}if(l!=st[tp]){st[++tp]=l;}st[++tp]=t[i];}while(tp!=1){nt.be(st[tp],st[tp--]);}ans=0;nt.dp(1,0);printf("%lld\n",ans);}return 0;}/*10 5cdbceabeae2 5 85 6 8 2 1 10 5 4 6 2 8 9 5 9 4 5 8 2 5 4 5 3 9 10 */


0 0