• 【BZOJ1125】【POI2008】poc


    题意:

    Description

    n列火车,每条有l节车厢。每节车厢有一种颜色(用小写字母表示)。有m次车厢交换操作。求:对于每列火车,在交换车厢的某个时刻,与其颜色完全相同的火车最多有多少。

    Input

    n l m (2 ≤ n ≤ 1000, 1 ≤ l ≤ 100, 0 ≤ m ≤ 100000) n行字符串,长度为l

    m行,每行4个数a b c d,a车的第b个字符与c车第d个字符交换。

    Output

    n个数,在交换车厢的某个时刻,与该车颜色完全相同的火车最多数目。

    题解:

    由于$l$很小,可以直接哈希判断两列火车是否相同;

    用splay来维护所有火车的哈希值,每次交换操作直接删除两个串的哈希值,交换字符重新计算哈希值后再插入即可;

    每次下传标记的时候把哈希值相同的一段打上标记更新答案;

    注意当交换的两个字符在同一个串中时要特殊处理,防止被删两次;

    时间复杂度$O((l+logn)m)$

    然而说起来很简单但我每次写平衡树都要调至少1h /微笑

    代码:

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<queue>
      7 #define inf 2147483647
      8 #define eps 1e-9
      9 #define H 173
     10 using namespace std;
     11 typedef unsigned long long ll;
     12 typedef double db;
     13 struct node{
     14     int son[2],fa,siz;
     15 }t[10001];
     16 int n,l,m,x,y,a,b,rt,cnt=0,ans[10001],tag[10001];
     17 ll pw[101],hs[10001];
     18 char s[1001][101];
     19 bool Son(int u){
     20     return t[t[u].fa].son[1]==u;
     21 }
     22 void pushup(int u){
     23     t[u].siz=t[t[u].son[0]].siz+t[t[u].son[1]].siz+1;
     24 }
     25 void pd(int u){
     26     if(tag[u]){
     27         ans[t[u].son[0]]=max(ans[t[u].son[0]],tag[u]);
     28         tag[t[u].son[0]]=max(tag[t[u].son[0]],tag[u]);
     29         ans[t[u].son[1]]=max(ans[t[u].son[1]],tag[u]);
     30         tag[t[u].son[1]]=max(tag[t[u].son[1]],tag[u]);
     31         tag[u]=0;
     32     }
     33 }
     34 void rotate(int u){
     35     int f=t[u].fa,ff=t[f].fa,ch=Son(u),cf=Son(f);
     36     pd(f);
     37     pd(u);
     38     t[f].son[ch]=t[u].son[ch^1];
     39     t[t[f].son[ch]].fa=f;
     40     t[ff].son[cf]=u;
     41     t[u].son[ch^1]=f;
     42     t[u].fa=ff;
     43     t[f].fa=u;
     44     pushup(f);
     45     pushup(u);
     46 }
     47 void splay(int u,int to){
     48     for(;t[u].fa!=to;rotate(u)){
     49         int f=t[u].fa;
     50         if(t[f].fa!=to)rotate(Son(u)^Son(f)?u:f);
     51     }
     52     if(!to)rt=u;
     53 }
     54 int getpre(ll x){
     55     int nw=rt,u=rt;
     56     for(;nw;){
     57         if(x>hs[nw]){
     58             u=nw;
     59             nw=t[nw].son[1];
     60         }else nw=t[nw].son[0];
     61     }
     62     return u;
     63 }
     64 int getnxt(ll x){
     65     int nw=rt,u;
     66     for(;nw;){
     67         if(x<hs[nw]){
     68             u=nw;
     69             nw=t[nw].son[0];
     70         }else nw=t[nw].son[1];
     71     }
     72     return u;
     73 }
     74 int nxt(int u){
     75     int nw=t[u].son[1];
     76     while(t[nw].son[0])nw=t[nw].son[0];
     77     return nw;
     78 }
     79 void ins(int x){
     80     int u=getpre(hs[x]),v=getnxt(hs[x]);
     81     splay(u,0);
     82     splay(v,u);
     83     t[x].son[0]=t[v].son[0];
     84     t[t[x].son[0]].fa=x;
     85     t[v].son[0]=x;
     86     t[x].fa=v;
     87     pushup(x);
     88     pushup(v);
     89     pushup(u);
     90     ans[x]=max(ans[x],t[x].siz);
     91     tag[x]=max(tag[x],t[x].siz);
     92 }
     93 void del(int x){
     94     splay(x,0);
     95     int u=nxt(x);
     96     splay(u,x);
     97     rt=u;
     98     t[u].son[0]=t[x].son[0];
     99     t[t[u].son[0]].fa=u;
    100     t[u].fa=0;
    101     pushup(u);
    102     t[x].son[0]=t[x].son[1]=0;
    103     t[x].siz=1;
    104 }
    105 void dfs(int u){
    106     pd(u);
    107     if(t[u].son[0])dfs(t[u].son[0]);
    108     if(t[u].son[1])dfs(t[u].son[1]);
    109 }
    110 int main(){
    111     scanf("%d%d%d",&n,&l,&m);
    112     pw[0]=1;
    113     for(int i=1;i<=l;i++)pw[i]=pw[i-1]*H;
    114     rt=n+1;
    115     t[rt].siz=2;
    116     hs[rt]=0;
    117     t[rt].son[1]=n+2;
    118     t[n+2].siz=1;
    119     t[n+2].fa=rt;
    120     hs[n+2]=(1ll<<64)-1;
    121     for(int i=1;i<=n;i++){
    122         scanf("%s",s[i]+1);
    123         for(int j=1;j<=l;j++){
    124             hs[i]=hs[i]*H+s[i][j];
    125         }
    126         ins(i);
    127     }
    128     for(int i=1;i<=m;i++){
    129         scanf("%d%d%d%d",&x,&a,&y,&b);
    130         if(x==y){
    131             del(x);
    132             swap(s[x][a],s[x][b]);
    133             hs[x]=0;
    134             for(int j=1;j<=l;j++){
    135                 hs[x]=hs[x]*H+s[x][j];
    136             }
    137             ins(x);
    138         }else{
    139             del(x);
    140             del(y);
    141             swap(s[x][a],s[y][b]);
    142             hs[x]=hs[y]=0;
    143             for(int j=1;j<=l;j++){
    144                 hs[x]=hs[x]*H+s[x][j];
    145                 hs[y]=hs[y]*H+s[y][j];
    146             }
    147             ins(x);
    148             ins(y);
    149         }
    150     }
    151     dfs(rt);
    152     for(int i=1;i<=n;i++){
    153         printf("%d
    ",ans[i]);
    154     }
    155     return 0;
    156 }
  • 相关阅读:
    第三章 SpringCloud之Eureka-Client服务提供者
    第二章 SpringCloud之Eureka-Server服务发现组件
    第一章 SpringCloud简介
    Storm之WordCount初探
    Solr之java实现增删查操作
    Solr安装并导入mysql数据
    java之消息队列ActiveMQ实践
    Ant Design使用方法
    Reactjs之实现js跳转路由
    React之js实现跳转路由
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/10231718.html
Copyright © 2020-2023  润新知