hdu 6190 & hdu 6192
阿新 • • 發佈:2018-12-31
hdu 6190 Matching in a Tree
容易發現
的字首
為
的一個子串滿足單調性,即若
為
的一個子串,那麼
必然是
的一個子串。故查詢實際上只需要計算對於
,最大的滿足要求的
是否滿足
。
設
表示
的長度為
的字尾是否是
的一個字首,
表示在
的字首中,第
個位置能否為
字元。那麼有:
用Bitset優化,計算出所有節點的
後再求每個節點的
的字首或即可。總複雜度為
。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
//--Container
#include<stack>
#include<queue>
#include<vector>
#include<bitset>
//--
#define clr(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef bitset<1001> bt;
const ll md=1e9+7;const int up=1e6;
bt sd[26],wg[up+10];
struct eg{int u,v,nx;char x;}gp[up+10];int cnt,hd[up+10],qry[up+10][2],qn;
inline ll qni(ll a,ll b){ll r=1;for(;b;b>>=1,a=a*a%md)if(b&1)r=r*a%md;return r;};
inline void psh(int u,int v,char x){++cnt;gp[cnt].u=u,gp[cnt].v=v,gp[cnt].x=x,gp[cnt].nx=hd[u],hd[u]=cnt;};
void dfs(){
int i,j;stack<int>stk;stk.push(0);for(;!stk.empty();){
int v=stk.top();stk.pop();for(i=hd[v];i;i=gp[i].nx){
wg[gp[i].v]=(wg[v]<<1)&sd[gp[i].x-'a'];wg[gp[i].v][0]=1;stk.push(gp[i].v);
}
}
for(stk.push(0);!stk.empty();){
int v=stk.top();stk.pop();for(i=hd[v];i;i=gp[i].nx){
wg[gp[i].v]|=wg[v];stk.push(gp[i].v);
}
}
};
bool cl(){
int i,j,a,b,t,d,m;char cz[10],dz[10];if(scanf("%d",&m)==-1)return 0;
for(i=0;i<26;sd[i++].reset());
for(d=qn=cnt=0,clr(hd);m;m--){
scanf("%s",cz);if(cz[1]=='D'){
scanf("%d %d %s",&a,&b,cz);psh(a,b,cz[0]);
}
else if(cz[1]=='S'){
scanf("%d %d %d",&a,&i,&b);qry[qn][0]=a,qry[qn][1]=b;++qn;
}
else{
scanf("%s %s",cz,dz);for(++d,i=cz[0];i<=dz[0];++i)sd[i-'a'][d]=1;
}
}
wg[0].reset();wg[0][0]=1;dfs();ll rs=0,be=qn?qni(233,qn-1):0,zn=qni(233,md-2);for(i=0;i<qn;++i,be=be*zn%md)
rs=(rs+be*(wg[qry[i][1]][qry[i][0]]?1:2)%md)%md;
printf("%lld\n",rs);
return 1;
};
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(cl());
return 0;
};
hdu 6192 Removing Mountains
容易發現題目實際上是在求修改1個位置後可能的最長公共前後綴。
對於字首
與字尾
,除非
,否則最多隻存在2個可修改點使得他們相等:
設
,
指他們的最長公共字首長度。
那麼這2個點為
與
。
故用擴充套件KMP求出 的值,之後對於每個 ,分別修改一次對應的2個點,同時用hash判斷即可。總複雜度為 。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
//--Container
#include<vector>
//--
#define clr(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef unsigned int ui;
const int up=1e6;const ui bse=131;char cz[up+10];int n,nxt[up+10];ui pr[up+10],xx[up+10];
void _exkmp(){
int i,j,k,d,t,mx,mz;for(nxt[0]=n,nxt[1]=0,j=1,k=0;j<n&&cz[j]==cz[k];++j,++k)++nxt[1];mx=--j,mz=1;
for(i=2;i<n;++i){
if(mx<i){for(nxt[i]=0,j=i,k=0;j<n&&cz[j]==cz[k];++j,++k)nxt[i]++;mx=--j,mz=i;}
else{
if(i+nxt[i-mz]-1<mx)nxt[i]=nxt[i-mz];
else{
for(nxt[i]=mx-i+1,j=mx+1,k=mx-i+1;j<n&&cz[j]==cz[k];++j,++k)++nxt[i];mx=--j,mz=i;
}
}
}
};
inline ui _seg(int l,int