模板测试

lct [NOI2014]魔法森林 

#include <bits/stdc++.h>
using namespace std;
const int N=2e5;
int v[N],data[N],data2[N],leftson[N],rightson[N],fa[N],n,m;
bool rev[N];
struct re {
    int a,b,c,d;
}a[N*2];
void updata(int x)
{
    data[x]=max(v[x],max(data[leftson[x]],data[rightson[x]]));
    if (data[x]==v[x]) data2[x]=x;
    if (data[x]==data[leftson[x]]) data2[x]=data2[leftson[x]];
    if (data[x]==data[rightson[x]]) data2[x]=data2[rightson[x]];
}
void down(int x)
{
    if (!rev[x]) return;
    swap(leftson[x],rightson[x]);
    rev[leftson[x]]^=1; rev[rightson[x]]^=1;
    rev[x]=0;
}
bool pd(int x)
{
    if (leftson[fa[x]]!=x&&rightson[fa[x]]!=x) return(0);
    else return(1);
}
void rotate(int x,int y)
{
    int father=fa[x];
    if (y==1)
    {
        rightson[father]=leftson[x];
        if (leftson[x]) fa[leftson[x]]=father;
    } else
    {
        leftson[father]=rightson[x];
        if (rightson[x]) fa[rightson[x]]=father;
    }
    fa[x]=fa[father];
    if (pd(father))
    {
        if (leftson[fa[x]]==father) leftson[fa[x]]=x;
        else rightson[fa[x]]=x;
    }
    if (y==1) leftson[x]=father; else rightson[x]=father;
    fa[father]=x;
    updata(father); updata(x);
}
void dfs(int x)
{
    if (pd(x)) dfs(fa[x]);
    down(x);
}
void splay(int x)
{
    dfs(x);
    int father=fa[x];
    while (pd(x))
    {
        if (!pd(father))
        {
            if (leftson[father]==x) rotate(x,2); else rotate(x,1);
        } else
        {
            if (leftson[fa[father]]==father)
              if (leftson[father]==x)
                rotate(father,2),rotate(x,2);
              else rotate(x,1),rotate(x,2);
            else 
              if (rightson[father]==x)
                rotate(father,1),rotate(x,1);
              else rotate(x,2),rotate(x,1);
        }
        father=fa[x];
    }
}
void access(int x)
{
    for (int y=0;x;y=x,x=fa[x])
      splay(x),rightson[x]=y,updata(x);
}
void makeroot(int x)
{
    access(x);
    splay(x);
    rev[x]^=1;
}
int findroot(int x)
{
    access(x);
    splay(x);
    while (leftson[x]) x=leftson[x];
    return x;
}
void split(int x,int y)
{
    makeroot(x);
    access(y);
    splay(y);
}
void cut(int x,int y)
{
    makeroot(x);
    if (findroot(y)==x&&fa[x]==y&&!rightson[x])
      fa[x]=leftson[y]=0;
}
void link(int x,int y)
{
    makeroot(x);
    if (findroot(y)!=x) fa[x]=y;
}
bool cmp(re x,re y)
{
    return(x.c<y.c);
}
bool find(int x,int y)
{
    makeroot(x);
    if (findroot(y)==x) return(1);
    else return(0);
}
int main()
{
    freopen("noip.in","r",stdin);
    freopen("noip.out","w",stdout);
    cin>>n>>m;
    for (int i=1;i<=m;i++) cin>>a[i].a>>a[i].b>>a[i].c>>a[i].d;
    sort(a+1,a+m+1,cmp);
    int ans=1e9;
    for (int i=1;i<=m;i++)
    {
        int x=a[i].a,y=a[i].b;
        if (find(x,y))
        {
            split(x,y);
            if (data[y]>a[i].d)
            {
                int p=data2[y];
                cut(p,a[p-n].a);
                cut(p,a[p-n].b);
                v[i+n]=a[i].d;
                link(i+n,x);
                link(i+n,y);
            }
        } else
        {
            v[i+n]=a[i].d;
            link(i+n,x);
            link(i+n,y);
        }
        if (find(1,n))
        {
            split(1,n);
            ans=min(ans,a[i].c+data[n]);
        }
    }
    if (ans==1e9) cout<<-1;
    else cout<<ans;
}

 AC自动机 hdu 2825

#include <bits/stdc++.h>
using namespace std;
#define mo 20090717 
int dy[2000],cnt,dp[27][250][1050],w[2000],ff[500][27],fail[500];
int n,m,kk;
char c[1000009];
void insert(char *s,int x)
{
    int now=0;
    for (int i=0;i<strlen(s);i++)
      if (ff[now][s[i]-'a']) now=ff[now][s[i]-'a'];
      else ff[now][s[i]-'a']=++cnt,now=cnt;
    w[now]|=1<<(x-1);
}
queue<int> q;
void build()
{
    for (int i=0;i<26;i++) if (ff[0][i]) q.push(ff[0][i]);
    while (!q.empty())
    {
        int x=q.front(); q.pop();
        for (int i=0;i<26;i++)
        {
          if (ff[x][i])
          {
              fail[ff[x][i]]=ff[fail[x]][i];
              q.push(ff[x][i]);
          } else ff[x][i]=ff[fail[x]][i];
          w[ff[x][i]]|=w[ff[fail[x]][i]];
        }
    }
}
int main()
{
    freopen("noip.in","r",stdin);
    freopen("noip.out","w",stdout);
    for (int i=1;i<=1028;i++)
    {
        int l=0;
        for (int j=0;j<=10;j++)
          if ((i>>j)%2==1) l++;
        dy[i]=l;
    }
    while (cin>>n>>m>>kk&&n)
    {
        memset(ff,0,sizeof(ff));
        memset(w,0,sizeof(w));
        memset(dp,0,sizeof(dp));
        memset(fail,0,sizeof(fail));
        for (int i=1;i<=m;i++)
        {
          cin>>c;
          insert(c,i);
        }
        build();
        dp[0][0][0]=1;
        for (int i=0;i<n;i++)
          for (int j=0;j<=cnt;j++)
            for (int k=0;k<=(1<<m)-1;k++)
              if (dp[i][j][k])
                 for (int u=0;u<26;u++)
                 {
                     int v=ff[j][u];
                    dp[i+1][v][k|w[v]]+=dp[i][j][k];
                    dp[i+1][v][k|w[v]]%=mo;
                 }
        int ans=0;
        for (int k=0;k<=(1<<m)-1;k++)
          if (dy[k]>=kk)
            for (int j=0;j<=cnt;j++)
              ans+=dp[n][j][k],ans%=mo;
        cout<<ans<<endl;
    }
    return 0;
}

 kmp 写矩阵的时候总会犯一些zz错误。。比如没有返回值,行列搞反

[HNOI2008]GT考试

#include <bits/stdc++.h>
using namespace std;
int n,m,mo1,fail[100];
char c[100];
struct re{
    int jz[30][30];
}a;
void get_fail()
{
    for (int i=1;i<strlen(c);i++)
    {
        int x=fail[i];
        while (x&&c[i]!=c[x]) x=fail[x];
        fail[i+1]=c[i]==c[x]?x+1:0;
    }
}
int find(int x,char cc)
{
    while (x&&c[x]!=cc) x=fail[x];
    if (c[x]==cc) x++;
    return(x);
}
re XX(re x,re y)
{
    re tmp;
    memset(tmp.jz,0,sizeof(tmp.jz));
    int len=strlen(c);
    for (int i=1;i<=len;i++)
      for (int j=1;j<=len;j++)
        for (int k=1;k<=len;k++)
          tmp.jz[i][k]+=x.jz[i][j]*y.jz[j][k],
          tmp.jz[i][k]%=mo1;
    return(tmp);
}
re fast_pow(int x)
{
    if (x==1) return(a);
    re b=fast_pow(x/2);
    b=XX(b,b);
    if (x%2==1) b=XX(b,a);
    return b;
}
int main()
{
    freopen("noip.in","r",stdin);
    freopen("noip.out","w",stdout);
    std::ios::sync_with_stdio(false);
    cin>>n>>m>>mo1;
    cin>>c;
    get_fail();
    for (int i=0;i<strlen(c);i++)
      for (int j=0;j<10;j++)
        if (find(i,j+'0')!=strlen(c))
          a.jz[find(i,j+'0')+1][i+1]++,
          a.jz[find(i,j+'0')+1][i+1]%=mo1;
    re d=fast_pow(n);
    int ans=0;
    for (int i=0;i<strlen(c);i++)
      ans+=d.jz[i+1][1],ans%=mo1;
    cout<<ans;    
    return 0;
}

矩阵优化 循环矩阵乘起来还是循环矩阵

 

树链剖分

平衡树

线段树

 序列记树

posted @ 2018-03-16 08:51  尹吴潇  阅读(210)  评论(0编辑  收藏  举报