• 解题:SCOI 2012 喵星球上的点名


    题面

    初见广义SAM

    建立广义SAM,每次把询问走一遍,最终走到节点的子树里的猫老师都被这次点名点到

    这样DFS parent树打时间戳记录入栈出栈时间,把问题转化成一个序列问题:给一个若干种颜色构成的序列和一些区间,询问:

    1.每个区间里有多少种颜色— —直接莫队

    2.每种颜色被多少区间包含— —同样是莫队,当某种颜色消失时从它上次出现开始的区间到现在的区间都包含了它

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<unordered_map>
      6 using namespace std;
      7 const int N=400005;
      8 struct a
      9 {
     10     int l,r;
     11     int idx,blo;
     12 }q[N];
     13 unordered_map<int,int> trs[N];
     14 int fth[N],len[N],bel[N];
     15 int p[N],noww[N],goal[N];
     16 int ins[N],ots[N],col[N];
     17 int qry[N],bkt[N],las[N],ans1[N],ans2[N];
     18 int n,m,lp,rp,ll,rd,lst,sqr,cnt,tot,dfn,ans;
     19 bool cmp(a x,a y)
     20 {
     21     return x.blo==y.blo?x.r<y.r:x.blo<y.blo;
     22 }
     23 void Link(int f,int t)
     24 {
     25     noww[++cnt]=p[f];
     26     goal[cnt]=t,p[f]=cnt;
     27 }
     28 void Insert(int ch)
     29 {
     30     int nde=lst,newn=++tot; 
     31     lst=newn,len[newn]=len[nde]+1;
     32     while(nde&&!trs[nde][ch])
     33         trs[nde][ch]=newn,nde=fth[nde];
     34     if(!nde)
     35         fth[newn]=1;
     36     else
     37     {
     38         int tran=trs[nde][ch];
     39         if(len[tran]==len[nde]+1)
     40             fth[newn]=tran;
     41         else
     42         {
     43             int rnde=++tot; 
     44             len[rnde]=len[nde]+1,trs[rnde]=trs[tran];
     45             fth[rnde]=fth[tran],fth[tran]=fth[newn]=rnde;
     46             while(nde&&trs[nde][ch]==tran)
     47                 trs[nde][ch]=rnde,nde=fth[nde];
     48         }
     49     }
     50 }
     51 void DFS(int nde)
     52 {
     53     ins[nde]=++dfn,col[dfn]=bel[nde];
     54     for(int i=p[nde];i;i=noww[i])
     55         DFS(goal[i]); ots[nde]=dfn;
     56 }
     57 void Add(int tsk,int typ)
     58 {
     59     if(tsk)
     60         if(++bkt[tsk]==1)
     61             ans++,las[tsk]=typ;
     62 }
     63 void Delete(int tsk,int typ)
     64 {
     65     if(tsk)
     66         if(!(--bkt[tsk]))
     67             ans--,ans2[tsk]+=typ-las[tsk];
     68 }
     69 int main()
     70 {
     71     scanf("%d%d",&n,&m),tot=1;
     72     for(int i=1;i<=n;i++)
     73     {
     74         scanf("%d",&ll),lst=1;
     75         for(int j=1;j<=ll;j++)
     76             scanf("%d",&rd),Insert(rd),bel[lst]=i;
     77         scanf("%d",&ll),lst=1;
     78         for(int j=1;j<=ll;j++)
     79             scanf("%d",&rd),Insert(rd),bel[lst]=i;
     80     }
     81     for(int i=2;i<=tot;i++) Link(fth[i],i); 
     82     DFS(1),sqr=sqrt(tot)+5;
     83     for(int i=1;i<=m;i++)
     84     {
     85         scanf("%d",&ll);
     86         for(int j=1;j<=ll;j++)
     87             scanf("%d",&qry[j]);
     88         int nde=1;
     89         for(int j=1;j<=ll;j++)
     90         {
     91             nde=trs[nde][qry[j]];
     92             if(!nde) break;
     93         }
     94         q[i].l=ins[nde],q[i].r=ots[nde];
     95         q[i].idx=i,q[i].blo=(q[i].l-1)/sqr+1;
     96     }
     97     sort(q+1,q+1+m,cmp),lp=1,rp=0;
     98     for(int i=1;i<=m;i++)
     99     {
    100         while(lp<q[i].l) Delete(col[lp++],i);
    101         while(lp>q[i].l) Add(col[--lp],i);
    102         while(rp<q[i].r) Add(col[++rp],i);
    103         while(rp>q[i].r) Delete(col[rp--],i);
    104         ans1[q[i].idx]=ans;
    105     }
    106     for(int i=lp;i<=rp;i++) Delete(col[i],m+1);
    107     for(int i=1;i<=m;i++) printf("%d
    ",ans1[i]);
    108     for(int i=1;i<=n;i++) printf("%d ",ans2[i]);
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    1834. 单线程 CPU sort+优先队列 过了,学习vector<vector<int>>排序
    552. 学生出勤记录 II 力扣(困难) 记忆化搜索/dp 不会做,学习记忆化搜索转dp的学习
    526. 优美的排列 力扣(中等) dfs暴搜/ 状压dp是没想到的
    576. 出界的路径数 力扣(中等) 路径dp/记忆化搜索 都不会做
    1583. 统计不开心的朋友 力扣(中等) 模拟,思考一下
    233. 数字 1 的个数 力扣(困难) 数位dp/数学 不会做
    516. 最长回文子序列 力扣(中等) 区间dp,不会做
    446. 等差数列划分 II
    7.14 数据结构板子
    7.13 树上问题
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10276996.html
Copyright © 2020-2023  润新知