• [2018湖南省队集训] 6.28 T3 simulate


        这道模拟题出的我毫无脾气2333

        最重要的是先要发现操作顺序不影响最后的答案,也就是每次随便挑一个>=2的数进行操作最后总是可以得到同样的数列。

        (这个还不太难想qwq)

        但是最骚的是接下来的模拟。。。。

        我们考虑从左到右消,假设目前在i,1~i-1的已经都消成了0或1。

        可以发现无非就是一下几种情况:

            1.a[i]<2,不用管它

            2.i==1,那么就 a[i+1]+=a[i]/2, a[i] &=1.

            3.左边都是1,这样的话推一推会发现,可以将一轮视为 a[1] = 0,a[i]-- ,a[i+1]++

            4.左边是1,推一推会发现这样相当于让 最近的一个0右移一位,然后a[i]--, a[i+1]++

            5.左边是0,直接算,a[i-1]++,a[i]-=2,a[i+1]++,会减少一个0位置

        如果我们用一个栈记录一下从左到右0的位置,那么就可以很方面的做上面的操作了。

        接下来是非常炫酷的复杂度分析!

            1操作的复杂度是O(N);

            2操作的复杂度是 O(1);

            3操作的最多次数不到初始所有a[]的和(因为每操作一次总和就--);

            4操作可以优化成一次位移最大(也就是要么把a[i]减成<2的,要么把0移到i-1),如果移到i-1然后再结合5操作的话它的次数 = 5操作的次数;否则因为a[i]<1了,扫描线会右移。所以这一部分的总次数 <= 2*n + 3操作的次数。

            5操作每次会让栈的大小-1,所以最多次数 <= 3操作的次数 + n。

    于是这个算法的复杂度是O(N) 的(并且算复杂度很多地方都是取的极限的情况,所以实际跑起来飞快),非常的优秀 (雾

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=20000005;
    
    int a[N],n,s[N],tp;
    char S[N];
    
    int main(){
    	freopen("simulate.in","r",stdin);
    	freopen("simulate.out","w",stdout);
    	
    	scanf("%s",S+1),n=strlen(S+1);
    	for(int i=1;i<=n;i++) a[i]=S[i]-'0';
    	
    	if(a[1]>=2) a[2]+=a[1]>>1,a[1]&=1;
    	if(!a[1]) s[++tp]=1;
    	
    	for(int i=2,L;i<=n;i++){
    	    while(a[i]>=2)
        		if(!tp) a[i+1]++,a[i]--,s[++tp]=1,a[1]=0;
        		else if(s[tp]==i-1) a[i]-=2,a[s[tp]]=1,tp--,a[i+1]++;
        		else{
        			L=i-s[tp]-1;
        			if(a[i]<=L) a[i+1]+=a[i]-1,a[s[tp]]=1,s[tp]+=a[i]-1,a[s[tp]]=0,a[i]=1;
        			else a[i+1]+=L,a[s[tp]]=1,s[tp]+=L,a[s[tp]]=0,a[i]-=L;
        		}
        	
        	if(!a[i]) s[++tp]=i;
        }
        
        for(int i=1;i<=n;i++) putchar(a[i]+'0');
        return 0;
    }
    

      

  • 相关阅读:
    PHP设计模式
    秒杀方案
    lua 安装
    docker 相关命令
    dockerfile
    JS工具对象 DATE 方法
    JS工具对象 Array
    JS工具对象 String 10种常用 方法
    工具对象
    JS工具对象Math 7个常用 方法
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9244562.html
Copyright © 2020-2023  润新知