zoukankan      html  css  js  c++  java
  • BZOJ4382 : [POI2015]Podział naszyjnika

    对于每种颜色,可以发现可以切的位置被分割成了若干段独立的区域。

    给每个区域一个编号,将$m$种颜色的情况当成字符串来看,如果两个切口的字符串完全匹配,那么可以在这里切两刀。

    可以构造hash函数,通过差分前缀和做到$O(n)$修改。

    然后对于每一种相同的hash值,将切口按位置从小到大排序,通过组合数计算方案数,再通过双指针计算最小差值。

    时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    #define N 1000010
    using namespace std;
    int n,m,i,j,k,y,g[N],nxt[N],ans=N;unsigned long long p,x,s[N],sum;
    inline bool cmp(int x,int y){return s[x]==s[y]?x<y:s[x]<s[y];}
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline int abs(int x){return x>0?x:-x;}
    int main(){
      read(n),read(m);
      for(i=1;i<=n;i++)read(j),nxt[i]=g[j],g[j]=i;
      for(i=p=1;i<=m;p*=1500007,i++){
        for(j=g[i],x=0;j;j=nxt[j]){
          if(nxt[j])s[nxt[j]]+=x;else s[1]+=x,s[g[i]]+=x;
          s[j]-=x,x+=p;
        }
      }
      for(i=1;i<=n;i++)s[i]+=s[i-1],g[i]=i;
      std::sort(g+1,g+n+1,cmp);
      for(i=1;i<=n;i=j+1){
        for(j=i;j<n&&s[g[i]]==s[g[j+1]];j++);
        for(k=y=i;k<=j;k++){
          if(y<=k)y=k+1;
          while(y<j&&abs(n-g[y]*2+g[k]*2)>=abs(n-g[y+1]*2+g[k]*2))y++;
          if(y<=j)ans=min(ans,abs(n-g[y]*2+g[k]*2));
        }
        sum+=1LL*(j-i+1)*(j-i)/2;
      }
      return printf("%llu %d",sum,ans),0;
    }
    

      

  • 相关阅读:
    -for循环案例(下)
    for循环案例(上)
    for循环
    判断语句案例
    判断语句
    操作符优先级
    windows 下安装图片标注软件 labelling和出错解决
    tf-faster rcnn
    目标检测——Faster R-CNN 详解、Pytorch搭建、训练自己的数据集
    java idea 配置安装
  • 原文地址:https://www.cnblogs.com/clrs97/p/5271144.html
Copyright © 2011-2022 走看看