12省联考???蒟蒻的试炼地,神犇的修罗场。

 [十二省联考2019]字符串问题

看代码吧,网上好多题解。主要是记录一下自己的sb错误(调了快3h。码力有所下降啊,关键是谁知道sort内部啥原理啊。。。)

  1 #include<bits/stdc++.h>
  2 #define LL long long
  3 #define In(i) (i*2-1)
  4 #define Out(i) (i*2) 
  5 using namespace std;
  6 const int maxn=2e5+5;
  7 int fst[maxn<<3],nxt[maxn<<6],to[maxn<<6],edge_count,id[maxn<<3];
  8 int w[maxn<<6];
  9 inline void add(int x,int y,int z){
 10     edge_count++;
 11     to[edge_count]=y;
 12     nxt[edge_count]=fst[x];
 13     fst[x]=edge_count;
 14     w[edge_count]=z;
 15     id[y]++;
 16 /*    if(edge_count<0 || edge_count>=(maxn<<6) || x<0 || y<0 || x>=(maxn<<3) || y>=(maxn<<3)){
 17         printf("GGGGGGGG");
 18         exit(0);
 19     }*/
 20 }
 21 int last,size,pos[maxn],cnt;
 22 struct Node{
 23     int trans[30];
 24     int parent,mx;
 25     Node(){
 26         parent=mx=0;
 27         memset(trans,0,sizeof trans);
 28     }
 29 }t[maxn<<1];
 30 inline void sam_init(){
 31     t[0].parent=-1;
 32     size=t[0].mx=last=0;
 33     memset(t[0].trans,0,sizeof t[0].trans);
 34 }
 35 inline void extend(int x){
 36     int np=++size,p=last;
 37     t[np].mx=t[p].mx+1;memset(t[np].trans,0,sizeof t[np].trans);
 38     while(!t[p].trans[x] && p!=-1){
 39         t[p].trans[x]=np;
 40         p=t[p].parent;
 41     }
 42     if(p==-1)t[np].parent=0;
 43     else{
 44         int q=t[p].trans[x];
 45         if(t[q].mx==t[p].mx+1)t[np].parent=q;
 46         else{
 47             int nq=++size;
 48             t[nq]=t[q];
 49             t[nq].mx=t[p].mx+1;
 50             t[q].parent=t[np].parent=nq;
 51             while(p!=-1 && t[p].trans[x]==q){
 52                 t[p].trans[x]=nq;
 53                 p=t[p].parent;
 54             }
 55         }
 56     }
 57     last=np;
 58 }
 59 LL dis[maxn<<3];
 60 int inque;
 61 queue<int>q;
 62 inline void topological_sort(){
 63     while(q.size())q.pop();
 64     memset(dis,0,sizeof dis);
 65     inque=0;
 66     LL ans=0;
 67     for(int i=0;i<=cnt;i++)
 68         if(!id[i]){
 69             q.push(i);
 70             inque++;
 71         }
 72     while(q.size()){
 73         int u=q.front();q.pop();
 74         ans=max(ans,dis[u]);
 75         for(int i=fst[u];i;i=nxt[i]){
 76             int v=to[i];
 77             dis[v]=max(dis[v],dis[u]+w[i]);
 78             id[v]--;
 79             if(!id[v]){
 80                 q.push(v);
 81                 inque++;
 82             }
 83         }
 84     }
 85     printf(inque<=cnt ? "-1\n" : "%lld\n",ans);
 86 }
 87 int T,n;
 88 char ch[maxn];
 89 int na,la[maxn],ra[maxn],ga[maxn],gb[maxn],nb,lb[maxn],rb[maxn],m;
 90 struct substr{
 91     int len;
 92     int isa;
 93     int num;
 94     substr(int Len=0,int Isa=false,int Num=0):len(Len),isa(Isa),num(Num){}
 95     inline bool operator<(const substr &S)const{
 96         return ( len<S.len || ( len==S.len && isa<S.isa) );
 97     }
 98 };
 99 vector<substr> V[maxn<<1];
100 int f[maxn<<1][25];
101 inline void clear(){
102     memset(fst,0,sizeof fst);
103     memset(id,0,sizeof id);
104     //memset(f,0,sizeof f);
105     for(int i=0;i<=size;i++)V[i].clear();
106     edge_count=0;
107 }
108 int main(){
109     scanf("%d",&T);
110     while(T--){
111         sam_init();
112         scanf("%s",ch+1);
113         n=strlen(ch+1);
114         for(int i=n;i;i--)extend(ch[i]-'a'),pos[i]=last;
115         for(int i=0;i<=size;i++){
116             f[i][0]=t[i].parent;
117             //printf("%d pa%d\n",i,t[i].parent);
118             //for(int j=0;j<26;j++)if(t[i].to[j])printf("%d %d\n",j,t[i].to[j]);
119         }
120         for(int i=1;i<=20;i++)for(int j=0;j<=size;j++)
121             f[j][i]=( f[j][i-1]==-1 ? -1 : f[f[j][i-1]][i-1] );//,printf("%d %d %d\n",j,i,f[j][i]);
122         cnt=(size<<1);
123         scanf("%d",&na);
124         for(int i=1;i<=na;i++){
125             scanf("%d%d",&la[i],&ra[i]);
126             ra[i]=(ra[i]-la[i]+1);
127             la[i]=pos[la[i]];
128             for(int j=20;j>=0;j--)if(f[ la[i] ][j]!=-1 && t[ f[la[i]][j] ].mx>=ra[i])la[i]=f[ la[i] ][j];
129             //printf("%d\n",la[i]);
130             V[la[i]].push_back(substr(ra[i],1,++cnt));
131             ga[i]=cnt;
132         }
133         scanf("%d",&nb);
134         for(int i=1;i<=nb;i++){
135             scanf("%d%d",&lb[i],&rb[i]);
136             rb[i]=(rb[i]-lb[i]+1);
137             lb[i]=pos[lb[i]];
138             for(int j=20;j>=0;j--)if(f[ lb[i]][j]!=-1 && t[ f[lb[i]][j] ].mx>=rb[i])lb[i]=f[ lb[i] ][j];
139             //printf("%d\n",lb[i]);
140             V[lb[i]].push_back(substr(rb[i],0,++cnt));
141             gb[i]=cnt;
142         }
143         for(int i=1;i<=size;i++){
144             add(Out(t[i].parent),In(i),0);
145             add(In(i),Out(i),0);//in -> out
146             sort(V[i].begin(),V[i].end());
147             /* 
148             !!!??? sort 出shit了??? 
149             认真的分析一下究竟是为什么我调了将近3h,
150             sort函数在比较的时候,必须要有< or cmp函数的bool 
151             返回值,但本人之前的写法,可能会导致cmp函数没有返回值, 
152             先填A串再填B串,然后都是B串的话就没法比较了吧。不知道。挺懵逼的 
153             不是。好像是因为。等长的B串之间,比较的话,都是B>=B然后一直swap? 
154             */
155             int lstb=0;
156             for(int j=0;j<V[i].size();j++){
157                 //printf("%d %d %d\n",V[i][j].len,V[i][j].isa,V[i][j].num);
158                 if(V[i][j].isa){
159                     add(In(i),V[i][j].num,V[i][j].len);//in -> A
160                     if(lstb)add(lstb,V[i][j].num,V[i][j].len);//B -> A
161                 }
162                 else {
163                     if(lstb)add(lstb,V[i][j].num,0);
164                     lstb=V[i][j].num;
165                 }
166             }
167             if(lstb)add(lstb,Out(i),0);
168         }
169         scanf("%d",&m);
170         for(int i=1,x,y;i<=m;i++){
171             scanf("%d%d",&x,&y);
172             add(ga[x],gb[y],0);
173         }
174         topological_sort();
175         clear();
176     }
177     return 0;
178 }
View Code

查错好方法:不断提交,屏蔽除输入输出之外的所有code。

问题分析(fp):

一开始很多bug:数组越界,没有清空之类。

终极bug(快2h):sort内部如何实现?如果两个东西来回比较的大小都是一样的,会怎样?

posted @ 2020-06-13 00:01  Tj1  阅读(99)  评论(0编辑  收藏  举报