zoukankan      html  css  js  c++  java
  • bzoj1125:[POI2008]Poc

    传送门

    这个题好难卡啊。
    看到这种题自然会想到字符串hash是不是,但是对于每次操作造成的影响需要(O(n))的时间去更新,自然是不优的
    可以发现这个更新可以用数据结构来维护,对于每个hash值开一颗线段树之类的支持区间修改的数据结构
    然后就可以愉快的解决了
    注意:
    1、hash值请使用map和unsigned long long存,否则会产生冲突
    2、特判a==c的情况
    3、map是真的慢,请不要在无(O(2))情况下使用
    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<map>
    using namespace std;
    void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    #define ull unsigned
    const int maxn=1e3+10,k=233,mod=1e5+7;
    int n,l,m,id,now,ans[maxn],la[mod*20],ls[mod*20],rs[mod*20];char ch[maxn][110];
    bool vis[mod*20];
    struct oo
    {
    	void update(int x){vis[x]=vis[ls[x]]|vis[rs[x]];}
        void pushdown(int x)
        {
            if(vis[ls[x]])la[ls[x]]=max(la[ls[x]],la[x]);
            if(vis[rs[x]])la[rs[x]]=max(la[rs[x]],la[x]);
            la[x]=0;
        }
        void add(int &k,int l,int r,int a,int b)
        {
            if(!k)k=++id;int mid=(l+r)>>1;
            if(l==r){ans[l]=max(ans[l],la[k]);vis[k]=b==1;return ;}
            if(la[k])pushdown(k);
            if(a<=mid)add(ls[k],l,mid,a,b);
            else add(rs[k],mid+1,r,a,b);
            update(k);
        }
        int get(int x,int l,int r,int a)
        {
            int mid=(l+r)>>1;
            if(l==r)return max(ans[l],la[x]);if(la[x])pushdown(x);
            if(a<=mid)return get(ls[x],l,mid,a);
            else return get(rs[x],mid+1,r,a);
        }
    };
    map<ull,oo>h;
    map<int,ull>w,ny;
    map<ull,int>sum,rt;
    int main()
    {
        read(n),read(l),read(m);
        for(rg int i=1;i<=n;i++)scanf("%s",ch[i]+1);ny[0]=1;
        for(rg int i=1;i<=l;i++)ny[i]=ny[i-1]*k;
        for(rg int i=1;i<=n;i++)
        {
            ull now=0;
            for(rg int j=1;j<=l;j++)now=now*k+ch[i][j]-'a';
            w[i]=now,h[now].add(rt[now],1,n,i,1),sum[now]++,la[rt[now]]=max(la[rt[now]],sum[now]);
        }
        for(rg int i=1,a,b,c,d;i<=m;i++)
        {
            read(a),read(b),read(c),read(d);swap(ch[a][b],ch[c][d]);
            if(a!=c)
            {
                h[w[a]].add(rt[w[a]],1,n,a,-1),h[w[c]].add(rt[w[c]],1,n,c,-1),sum[w[a]]--,sum[w[c]]--;
                w[a]=w[a]+(ch[a][b]-ch[c][d])*ny[l-b],w[c]=w[c]+(ch[c][d]-ch[a][b])*ny[l-d];
                h[w[a]].add(rt[w[a]],1,n,a,1),sum[w[a]]++,la[rt[w[a]]]=max(la[rt[w[a]]],sum[w[a]]);
                h[w[c]].add(rt[w[c]],1,n,c,1),sum[w[c]]++,la[rt[w[c]]]=max(la[rt[w[c]]],sum[w[c]]);
            }
            else 
            {
                h[w[a]].add(rt[w[a]],1,n,a,-1),h[w[c]].add(rt[w[c]],1,n,c,-1),sum[w[a]]--;
                w[a]=w[a]+(ch[a][b]-ch[c][d])*ny[l-b],w[c]=w[c]+(ch[c][d]-ch[a][b])*ny[l-d];
                h[w[a]].add(rt[w[a]],1,n,a,1),sum[w[a]]++,la[rt[w[a]]]=max(la[rt[w[a]]],sum[w[a]]);
            }
        }
        for(rg int i=1;i<=n;i++)printf("%d
    ",h[w[i]].get(rt[w[i]],1,n,i));
    }
    
  • 相关阅读:
    layui日历控件设置选择日期不能超过当前日期
    layui表格工具条,如何动态控制按钮的展示?
    celery定时任务
    redis的安装(windows+linux)
    redis常用操作
    mac通过virtualbox安装win10
    制作U盘启动盘
    k8s报错: * spec.template.spec.volumes[0].name: Invalid value: "nfs_pvc001": must match the regex [a-z0-9]([-a-z0-9]*[a-z0-9])? (e.g. 'my-name' or '123-abc')
    k8s的容器的端口暴露
    k8s中pod文件的定义格式
  • 原文地址:https://www.cnblogs.com/lcxer/p/10395218.html
Copyright © 2011-2022 走看看