BZOJ4295 : [PA2015]Hazard

第i轮,a[i%n]+=b[i%m]。

枚举i,计算它变为0的次数,假设为t,那么有t=i+kn。

对于所有的i和k,(i+kn)%m形成了若干个总长度为m的环。

对于每个a[i],先在环中求出一轮最多可以减少多少,以及一轮的增量是多少,由此可以求出在几轮后变为0。

再在前缀后缀分类讨论一下即可求出具体是在哪一局变为0。

时间复杂度$O(n+m)$。

#include<cstdio>
#define N 1000010
typedef long long ll;
const ll inf=2000000000000000000LL;
int n,m,i,j,k,x,a[N],b[N],v[N],t,q[N],s[N],pre[N],suf[N],g[N],c[N+N];ll f[N],ans=inf;char ch[N];
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 min(int a,int b){return a<b?a:b;}
inline ll min(ll a,ll b){return a<b?a:b;}
int main(){
  for(read(n);i<n;i++)read(a[i]),f[i]=inf,g[i]=N;
  for(read(m),scanf("%s",ch),i=0;i<m;i++)b[i]=ch[i]==‘W‘?1:-1;
  for(i=0;i<N+N;i++)c[i]=N;
  for(i=0;i<n;i++)if(!v[i%m]){
    for(t=0,j=i%m;!v[j];j=(j+n)%m)v[q[++t]=j]=1;
    for(j=1;j<=t;j++)s[j]=s[j-1]+b[q[j]];
    pre[0]=suf[t+1]=N;
    for(j=1;j<=t;j++)pre[j]=min(pre[j-1],s[j]);
    for(j=t;j;j--)suf[j]=min(suf[j+1],s[j]);
    for(j=1;j<=t;j++){
      x=min(pre[j-1]+s[t],suf[j])-s[j-1];
      for(k=q[j];k<n;k+=m)if(x+a[k]<=0)g[k]=0;else if(s[t]<0)g[k]=(x+a[k])/(-s[t])+((x+a[k])%(-s[t])>0);
    }
    for(j=1;j<=t;j++){
      for(k=q[j];k<n;k+=m)if(g[k]<N){
        x=c[s[j-1]-g[k]*s[t]-a[k]-s[t]+N];
        if(x<=t)f[k]=min(f[k],(1LL*g[k]*t+x-j+t)*n+k);
      }
      if(c[s[j]+N]>j)c[s[j]+N]=j;
    }
    for(j=1;j<=t;j++)c[s[j]+N]=N;
    for(j=t;j;j--){
      c[s[j]+N]=j;
      for(k=q[j];k<n;k+=m)if(g[k]<N){
        x=c[s[j-1]-g[k]*s[t]-a[k]+N];
        if(x<=t)f[k]=min(f[k],(1LL*g[k]*t+x-j)*n+k);
      }
    }
    for(j=1;j<=t;j++)c[s[j]+N]=N;
  }
  for(i=0;i<n;i++)ans=min(ans,f[i]+1);
  if(ans<inf)printf("%lld",ans);else puts("-1");
  return 0;
}

  

时间: 2024-10-08 10:50:35

BZOJ4295 : [PA2015]Hazard的相关文章

BZOJ 4291: [PA2015]Kieszonkowe 水题

4291: [PA2015]Kieszonkowe Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=4291 Description 给定n个数,请从中选出若干个数,使得总和为偶数,请最大化这个总和. Input 第一行包含一个正整数n(1<=n<=1000000). 第二行包含n个正整数a_1,a_2,...,a_n(1<=a_i<=1000).

CPU五级流水线工程(带Hazard)

工程简介: 计算机组成原理课程Project--五级流水线hazard处理 思路说明: CPU架构图: CPU指令集: 代码在这里:cpu_hazard

并行编程中的内存回收Hazard Pointer

接上篇使用RCU技术实现读写线程无锁,在没有GC机制的语言中,要实现Lock free的算法,就免不了要自己处理内存回收的问题. Hazard Pointer是另一种处理这个问题的算法,而且相比起来不但简单,功能也很强大.锁无关的数据结构与Hazard指针中讲得很好,Wikipedia Hazard pointer也描述得比较清楚,所以我这里就不讲那么细了. 一个简单的实现可以参考我的github haz_ptr.c 原理 基本原理无非也是读线程对指针进行标识,指针(指向的内存)要释放时都会缓存

机器学习基石——第13-14讲.Hazard of Overfitting

本栏目(机器学习)下机器学习基石专题是个人对Coursera公开课机器学习基石(2014)的学习心得与笔记.所有内容均来自Coursera公开课Machine Learning Foundations中Hsuan-Tien Lin林轩田老师的讲解.(https://class.coursera.org/ntumlone-002/lecture) 第13讲-------Hazard of Overfitting 从这一节开始,我们开始探讨How Can Machines Learn Better的

CPU五级流水线project(带Hazard)

project简单介绍: 计算机组成原理课程Project--五级流水线hazard处理 思路说明: CPU架构图: CPU指令集: 代码在这里:cpu_hazard

使用风险指针(hazard pointer) 处理无锁栈的 push 与 pop

constexpr size_t maxHazardPointers = 100; struct HazardPointer { std::atomic<std::thread::id> id; std::atomic<void*> pointer; }; array<HazardPointer, maxHazardPointers> hazardPointers; class HazardPointerOwner { HazardPointer* hazardPoin

wiredtiger - hazard pointers

http://www.drdobbs.com/lock-free-data-structures-with-hazard-po/184401890 memory deallocation  lock-free session.h /* * WT_HAZARD -- * A hazard pointer. */ struct __wt_hazard { WT_PAGE *page; /* Page address */ #ifdef HAVE_DIAGNOSTIC const char *file

upc组队赛14 Floating-Point Hazard【求导】

Floating-Point Hazard 题目描述 Given the value of low, high you will have to find the value of the following expression: \(\sum_{i=low}^{high}(\sqrt[3]{(i+10^{-15})}-\sqrt[3]i)\) If you try to find the value of the above expression in a straightforward w

when|nobody|hazard|lane|circuit|

How can I help them  they won't listen to me? 题目解析 考查从句.此句意为:如果他们要是不听我的话,我怎么帮助他们?此处,when引导的状语从句表示假设事件的发生,具有不确定性,意思为“如果”. I want to be famous! I am tired of being . 题目解析 考查代词的用法.此句意思是:我想出名,我讨厌做一个普通人.根据句意,空格处的意思应为“无足轻重的人物.小人物”,所以此处填入nobody. 然而none其后跟of