zoukankan      html  css  js  c++  java
  • JZOJ 3960 鸡腿の出行

    SOL: 

      我们可以用tarjan求割点和边双,然后便成了一颗树,问题转成了 树上两点距离。

    #include<bits/stdc++.h>
    #define ull unsigned long long 
    #define LL long long
    #define mo 998244353
    #define B 80
    using namespace std;
    //const int _P=1000007;
    //const int _N=1000005;
    //struct HashMap{
    //  int head[_P],inum,clk;
    //  int tag[_P];
    //  ull h[_N]; int c[_N],g[_N],next[_N];
    //  void _new(){
    //    ++clk; inum=0;
    //  }
    //  int Head(int x){
    //    return tag[x]!=clk?(tag[x]=clk,head[x]=0):head[x];
    //  }
    //  int &get(ull _h,int _c){
    //    int hs=(_h*233+_c)%_P;
    //    for (int p=Head(hs);p;p=next[p])
    //      if (h[p]==_h && c[p]==_c)
    //    return g[p];
    //    h[++inum]=_h; c[inum]=_c; g[inum]=0; next[inum]=head[hs]; head[hs]=inum;
    //    return g[inum];
    //  }
    //}f[2];
    struct Ha{
        #define HaN 1000007
        #define HaM 1000007
        int head[HaN],net[HaM],fall[HaM],tag[HaN],tot,tim,
        c[HaM],g[HaM];
        ull h[HaM];
        void _new() {++tim; tot=0;}
        int push(int x) {
            return (tag[x]^tim)?(tag[x]=tim,head[x]=0):head[x];
        }
        int &get(ull _h,int _c) {
            static int hs;
            hs=(_h*233+_c)%HaN;
            for (int i=push(hs);i;i=net[i]) 
             if (h[i]==_h&&c[i]==_c) return g[i];
            h[++tot]=_h,c[tot]=_c; g[tot]=0; net[tot]=head[hs]; head[hs]=tot;
            return g[tot];
        }
    }f[2];
    int n,m,g,p,c,nc; char ha[107],pa[107];
    LL K,ff[107][107],sum[107*107],l,r,ans;
    ull se[107],h,tt,nh;
    signed main () {
    //    freopen("c.in","r",stdin);
        scanf("%d%d%lld",&n,&m,&K);
        scanf("%s",ha+1); scanf("%s",pa+1);
        ff[1][1]=K;
        for (int i=1;i<=n;i++)
         for (int j=1;j<=m;j++)
          ff[i+1][j]+=ff[i][j]>>1,ff[i][j+1]+=ff[i][j]>>1,ff[i][j]&=1;
        for (int i=1;i<=n;i++) ans+=(ha[i]=='1')*ff[i][m+1],ff[i][m+1]=0;
        for (int i=1;i<=m;i++) ans+=(pa[i]=='1')*ff[n+1][i],ff[n+1][i]=0;
        se[0]=1; for (int i=1;i<=m;i++) se[i]=se[i-1]*B;
        int t=0; f[t]._new();
        ull tmp=0; for (int i=m;i;i--) tmp=tmp*B+ff[1][i];
        f[t].get(tmp,0)=1;
        for (int i=1;i<=n*m;i++,t^=1){
        int x=(i-1)/m+1,y=(i-1)%m+1;
        f[t^1]._new();
        for (int p=1;p<=f[t].tot;p++){
          h=f[t].h[p]; c=f[t].c[p],g=f[t].g[p];
          tt=h%80;
          nh=h/80+se[m-1]*ff[x+1][y]; nc=c;
          if (y<m) nh+=(tt+1)/2;
          else nc+=((tt+1)/2)*(ha[x]=='1');
          if (x<n) nh+=se[m-1]*(tt/2);
          else nc+=(tt/2)*(pa[y]=='1');
    //       cerr<<nh<<' '<<nc<<endl;
          (f[t^1].get(nh,nc)+=g)%=mo;
          nh=h/80+se[m-1]*ff[x+1][y]; nc=c;
          if (y<m) nh+=tt/2;
          else nc+=(tt/2)*(ha[x]=='1');
          if (x<n) nh+=se[m-1]*((tt+1)/2);
          else nc+=((tt+1)/2)*(pa[y]=='1');
    //      cerr<<nh<<' '<<nc<<endl;
          (f[t^1].get(nh,nc)+=g)%=mo;
        }
      }
        for (int q=1;q<=f[t].tot;q++) (sum[f[t].c[q]]+=f[t].g[q])%=mo;
        for (int i=1;i<=n*m;i++) (sum[i]+=sum[i-1])%=mo;
        scanf("%d",&p);
        while (p--) {
          scanf("%lld%lld",&l,&r);
          l=max(l,ans); r=min(r,ans+n*m);
          if (l>r){printf("0
    "); continue;}
          if (l==ans) printf("%d
    ",sum[r-ans]);
          else printf("%d
    ",(sum[r-ans]+mo-sum[l-ans-1])%mo);
        }
        return 0; 
    }
  • 相关阅读:
    springmvc整合elasticsearch
    测试中出现ERROR StatusLogger No log4j2 configuration file
    SpringBoot项目取消数据库配置
    centos7 更换jdk版本
    对前后端解耦的理解
    满足java对redis的所有操作,token,验证码过期时间等
    在spring的过滤器中注入实体类(@autowire会失效可使用这个方法)
    linux 下vim中关于删除某段,某行,或全部删除的命令
    解决问题Can’t connect to local MySQL server through socket
    centos6.5 mqtt安装
  • 原文地址:https://www.cnblogs.com/rrsb/p/9299172.html
Copyright © 2011-2022 走看看