T1.匹配
一看就是KMP的嘛,但是忘了。
啊,要背模板的啦!
啊?!暴力72分?!?!?! Get!
正解就是一般的KMP,把a串与b串接起来(之间加一点乱七八糟),然后get_next;
没了。
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define RE register 4 using namespace std; 5 inline int R(){ 6 RE char c=getchar();int x=0,t=1; 7 while(c<'0'||c>'9'){if(c=='-') t=-1;c=getchar();} 8 while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();} 9 return x*t; 10 } 11 const int maxn=5000010; 12 int la,lb,lc; 13 char a[maxn],b[maxn],c[maxn],d; 14 int nxt[maxn]; 15 void get_nxt(){ 16 int p=0;nxt[1]=0; 17 for(int i=2;i<=lc;i++){ 18 while(p&&c[p+1]!=c[i]) p=nxt[p]; 19 if(c[p+1]==c[i]) p++; 20 nxt[i]=p; 21 } 22 } 23 int main (){ 24 // freopen("in1.txt","r",stdin); 25 int t; 26 t=R(); 27 while(t--){ 28 la=R(),lb=R(); 29 scanf("%s",a+1); 30 cin>>d; 31 for(int i=1;i<=lb;i++) 32 b[i]=a[i]; 33 b[++lb]=d; 34 for(int i=1;i<=la;i++) c[i]=a[i]; 35 lc=la; 36 c[++lc]='~'; 37 c[++lc]='!'; 38 for(int i=1;i<=lb;i++) c[i+lc]=b[i]; 39 lc+=lb; 40 get_nxt(); 41 printf("%d ",nxt[lc]); 42 } 43 return 0; 44 }
T2.回家
考场:一看就是tarjan跑点双缩点,再干.......(dfs或拓扑或最短路或lca),但终究码力不行,码一半放弃了。
正解:就是这样的,缩点后建成圆方树,再跑dfs压栈。
某大佬提出:缩点后建树,再跑O(n)的lca(只记录父亲)。可行
又有大佬提出:跑最短路,边双缩点,据说不对,90分。
论加强码力的重要性。。。
等等!要开八倍空间!!!!!!!!!!!
圆方树开二倍,无向边开二倍,然后边开4倍,点开2倍。
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define RE register 4 using namespace std; 5 const int N=2e5+100; 6 const int maxn=N*2; 7 const int maxm=N*4; 8 inline int R(){ 9 RE char b=getchar();int x=0,t=1; 10 while(b<'0'||b>'9'){if(b=='-') t=-1;b=getchar();} 11 while(b>='0'&&b<='9') {x=(x<<3)+(x<<1)+b-'0';b=getchar();} 12 return x*t; 13 } 14 int n,m; 15 struct Edge{ 16 int f,nxt,to; 17 }ed[maxm],edg[maxm]; 18 int head[maxn],ecnt; 19 void addedge(int f,int to){ 20 ed[++ecnt].f=f; 21 ed[ecnt].to=to; 22 ed[ecnt].nxt=head[f]; 23 head[f]=ecnt; 24 } 25 int headg[maxn],egcnt; 26 void add(int f,int to){ 27 edg[++egcnt].f=f; 28 edg[egcnt].to=to; 29 edg[egcnt].nxt=headg[f]; 30 headg[f]=egcnt; 31 } 32 void input_(){ 33 n=R(),m=R(); 34 for(int i=1,a,b;i<=m;i++){ 35 a=R(),b=R(); 36 if(a==b) continue; 37 addedge(a,b); 38 addedge(b,a); 39 } 40 } 41 int sta[maxn],tp,root; 42 int dfn[maxn],low[maxn],num; 43 bool vis[maxn],cut[maxn]; 44 45 int dcc_num; 46 vector<int> dcc[maxn]; 47 void tarjan(int x){ 48 sta[++tp]=x; 49 int flag=0; 50 dfn[x]=low[x]=++num; 51 for(int i=head[x];i;i=ed[i].nxt){ 52 int v=ed[i].to; 53 if(!dfn[v]) { 54 tarjan(v); 55 low[x]=min(low[x],low[v]); 56 if(low[v]>=dfn[x]){ 57 flag++; 58 if(root!=x||flag>1) cut[x]=1; 59 int temp; 60 dcc_num++; 61 do{ 62 temp=sta[tp--]; 63 dcc[dcc_num].push_back(temp); 64 }while(temp!=v); 65 dcc[dcc_num].push_back(x); 66 } 67 } 68 else low[x]=min(low[x],dfn[v]); 69 } 70 } 71 72 int pos[maxn],biao[maxn]; 73 void work_(){ 74 num=dcc_num; 75 for(int i=1;i<=n;i++) 76 if(cut[i]) pos[i]=++num,biao[num]=i; 77 for(int i=1;i<=dcc_num;i++){ 78 for(int j=0;j<dcc[i].size();j++){ 79 if(cut[dcc[i][j]]) add(i,pos[dcc[i][j]]),add(pos[dcc[i][j]],i); 80 else pos[dcc[i][j]]=i; 81 } 82 dcc[i].clear(); 83 } 84 } 85 86 bool ok=0; 87 void dfs(int x) { 88 vis[x]=1; 89 if(x==pos[n]) {ok=1;return ;} 90 if(ok) return ; 91 for(int i=headg[x];i;i=edg[i].nxt){ 92 int v=edg[i].to; 93 if(vis[v]) continue; 94 if(biao[v]) sta[++tp]=biao[v]; 95 dfs(v); 96 if(biao[v]&&!ok) tp--; 97 if(ok) return ; 98 } 99 return ; 100 } 101 void clear_(){ 102 memset(ed,0,sizeof ed); 103 memset(edg,0,sizeof edg); 104 tp=0,ecnt=egcnt=num=0,ok=dcc_num=0; 105 memset(cut,0,sizeof cut); 106 memset(dfn,0,sizeof dfn); 107 memset(low,0,sizeof low); 108 memset(head,0,sizeof head); 109 memset(headg,0,sizeof headg); 110 memset(pos,0,sizeof pos); 111 memset(biao,0,sizeof biao); 112 } 113 int main(){ 114 // freopen("in_B.txt","r",stdin); 115 int t=R(); 116 while(t--){ 117 clear_(); 118 input_(); 119 root=1,tarjan(1);//dian shuang 120 // for(int i=1;i<=dcc_num;i++){ 121 // for(int j=0;j<dcc[i].size();j++) 122 // printf("%d ",dcc[i][j]); 123 // puts(""); 124 // } 125 // for(int i=1;i<=n;i++) if(cut[i]) cout<<i<<" "; 126 // puts(""); 127 // puts(""); 128 129 work_(); 130 tp=0; 131 memset(vis,0,sizeof vis); 132 dfs(pos[1]); 133 memset(vis,0,sizeof vis); 134 int ans=0; 135 while(tp){ 136 int tmp=sta[tp--]; 137 if(!vis[tmp]&&tmp!=1&&tmp!=n){ 138 ans++;vis[tmp]=1; 139 } 140 } 141 printf("%d ",ans); 142 for(int i=1;i<=n;i++) if(vis[i]) printf("%d ",i); 143 puts(""); 144 } 145 return 0; 146 }
T3.寿司
不会,先搁着吧。