A.匹配
顯然這個題可以用雜湊,也不用預處理,直接 \(O(1)\) 擴充就行了. \(A\) 擴充用 \(f'=f\times sum+A_{i}\),\(B\) 用 \(f'=f+B_{i}\times num^{i}\),自然溢位就行.
#include<bits/stdc++.h>
using namespace std;
#define speed ios::sync_with_stdio(false);
#define input(i) int (i);cin>>(i)
#define tests int cases;cin>>cases;while(cases--)
typedef unsigned long long hdk;
string a,b;char ch;
const hdk num=233;
hdk ah,bh,bnum=1,anow,bnow;
inline hdk ahash(){
ah=ah*num+a[anow];
++anow;return ah;
}
inline hdk bhash(){
bh+=bnum*b[bnow];
--bnow;bnum*=num;
return bh;
}
inline void clear(){
ah=0;bh=0;bnum=1;anow=0;bnow=b.length()-1;
}
signed main(){
#ifdef ONLINE_JUDGE
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
#endif
speed tests{
input(la);input(lb);
cin>>a;
b=a.substr(0,lb);
cin>>ch;b.push_back(ch);
clear();
int ans=0;
for(int i=1;i<=b.length();++i){
hdk m=ahash(),n=bhash();
if(m==n) ans=i;
}
cout<<ans<<endl;
}
}
B.回家
賽時打的是Tarjan割點,以為是純板子,然後發現單純割點跑不對(譴責這個堂食樣例跑什麼都能過),自己搓了一組資料才發現,割點不一定割的是 \(1\) 到 \(n\) 的路徑,統計這個答案必須要保證它割的這兩部分一個包含 \(1\) 另一個包含 \(n\) 才行. 所以就在 tarjan 裡套了個 dfs 然後遞迴炸了. 後來想到 tarjan 不就是搜嗎然後爆改 tarjan 拿了 \(60\) 分
賽時程式碼
#include <bits/stdc++.h>
using namespace std;
#define speed ios::sync_with_stdio(false);
#define input(i) int (i);cin>>(i)
#define tests int cases;cin>>cases;while(cases--)
int n,m;
struct node{
int dfn,low,vis;
bool cut;
}p[200001];
struct hdk{
int to,nxt;
}e[200001];
int head[200001],cnt,enow;
inline void add(int x,int y){
e[++enow]={y,head[x]};
head[x]=enow;
}
bool tarjan(int s,int root){
++cnt;
p[s].dfn=cnt;
p[s].low=cnt;
int child=0;
bool totcheck=false;
for(int i=head[s];i;i=e[i].nxt){
int tem=e[i].to;
if(p[tem].dfn==0){
++child;
bool check=tarjan(tem,s);
if(check) totcheck=true;
p[s].low=min(p[s].low,p[tem].low);
if(p[s].dfn<=p[tem].low){
if(s!=root||child>1){
if(check){
p[s].cut=1;
}
}
}
}
else{
p[s].low=min(p[s].low,p[tem].dfn);
}
}
if(s==n) return true;
return totcheck;
}
signed main(){
#ifdef ONLINE_JUDGE
freopen("home.in","r",stdin);
freopen("home.out","w",stdout);
#endif
speed tests{
cnt=0;enow=0;
memset(p,0,sizeof p);
memset(e,0,sizeof e);
memset(head,0,sizeof head);
cin>>n>>m;
for(int i=1;i<=m;++i){
input(x);input(y);
add(x,y);add(y,x);
}
tarjan(1,1);
int ans=0;
vector<int>an;
for(int i=2;i<=n-1;++i){
if(p[i].cut){
ans++;
an.push_back(i);
}
}
cout<<ans<<endl;
bool flg=false;
if(!an.empty()){
for(int i:an){
if(flg) cout<<" ";
cout<<i;
flg=true;
}
}
cout<<endl;
}
}
那麼錯哪了呢,顯然是統計多了,因為我是從 \(1\) 搜過來的,所以忘記判 \(1\) 是不是在另一邊了
但是這樣的話就不用爆改 tarjan 了,寫個 check 搞一下就行了.
考慮到如果 \(dfn[v]>dfn[u]\),則 \(v\) 在 \(u\) 的搜尋子樹中,所以我們需要找出一個點滿足下面的條件:
- \(v\) 在 \(1\) 的搜尋子樹中
- \(v\) 不在 \(n\) 的搜尋子樹中
或者 \(1\) 和 \(n\) 反過來也行.
所以跑個割點的基礎上判個 \(dfn\) 就行了
#include<bits/stdc++.h>
using namespace std;
bool sc=false;
#define tests int cases;cin>>cases;while(cases--)
#define speed ios::sync_with_stdio(false);
#define input(i) int (i);cin>>(i)
#define debug(i) if(sc)cout<<(i)<<endl
#define clears(i) memset((i),0,sizeof (i))
inline void start(){
#ifndef ONLINE_JUDGE
sc=true;
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
#ifdef ONLINE_JUDGE
freopen("home.in","r",stdin);
freopen("home.out","w",stdout);
#endif
string x="[TEST]";
debug(x);
debug(time(0));
}
vector<int>an;
int head[2000001],enow;
int n,m;
struct edge{
int u,v,next;
}e[800001];
inline void add(int u,int v){
e[++enow]={u,v,head[u]};
head[u]=enow;
return;
}
int dfn[200001],low[200001],cnt;
inline int check(int u,int v){
if(dfn[v]<=dfn[1]&&dfn[v]>dfn[n]) return 1;
if(dfn[v]<=dfn[n]&&dfn[v]>dfn[1]) return 1;
return 0;
}
void tarjan(int u,int fa){
dfn[u]=low[u]=++cnt;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=1&&u!=n&&check(u,v)){
an.push_back(u);
}
}
else if(v!=fa) low[u]=min(low[u],dfn[v]);
}
return;
}
inline void clearall(){
clears(e);
clears(head);
clears(low);
clears(dfn);
enow=0;
cnt=0;
an.clear();
}
signed main(){
start();
speed tests{
clearall();
cin>>n>>m;
while(m--){
int u,v;
cin>>u>>v;
add(u,v);
add(v,u);
}
tarjan(1,0);
sort(an.begin(),an.end());
cout<<an.size()<<endl;
for(int i:an){
cout<<i<<" ";
}
cout<<endl;
}
}
C.壽司
To be added