• [vijos1554&bzoj1411]硬币游戏<快速幂>


    题目链接:https://vijos.org/p/1554

        http://www.lydsy.com/JudgeOnline/problem.php?id=1411

    这题真的淫*QAQ。。。

    一看题还以为是啥水题,结果啊,是个规律题

    我们先来解释一下样例

    20202010101010101020   0
    01010201010101010201   1
    10102020101010102020   2
    01020102010101020102   3
    20202020201010202020   4
    01010101020102010101   5
    10101010202020201010   6
    01010102010101020101   7
    10101020201010202010   8
    01010201020102010201   9
    10102020202020202020   10
    01020101010101010102   11

    这后面的数字表示的是第几次操作

    然后可以开始找规律了。。。。。。。。。

    盯-----------------------------------------------------------------------------------------------------

    这个看起来头有点痛,我们优化一波来看

    20202010101010101020   0

    10102020101010102020   2

    20202020201010202020   4

    10101010202020201010   6

    10101020201010202010   8

    10102020202020202020   10

    其实我们就可以发现,这个每两次操作,硬币的位置是不会变的,变的只是正反面

    然后我们在把这个图继续变换

    20202010101010101020   0

    10102020101010102020   2

    20202020201010202020   4

    10101020201010202010   8

    我们只留下了2^k次方这些操作

    就可以发现,第2^k次方次操作中,第i个数是由最开始的i-2^k和i+2^k这两个数来决定的

    所以对于操作次数T

    要把T分解成2^k+2^k-1+···+2^1+1这种形式的

    其实吧,这就是快速幂

    然后快乐的写一个快速幂模板就过了

    只是注意一下T是2^60,要用long long存

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdlib>
     6 #include<queue>
     7 #include<cmath>
     8 #define maxn 200005
     9 using namespace std;
    10 
    11 int n;
    12 long long x,d=1;
    13 int a[maxn*2],b[maxn*2];
    14 
    15 int did(int pos,long long dis){
    16     int l=((pos-dis)%n+n)%n,r=(pos+dis)%n;
    17     //pos-dis有可能<-n; 
    18     if(l==0)l=n;if(r==0)r=n;
    19     if(a[l]==0)return 0;
    20     if(!(a[l]^a[r]))return 1;
    21     return 2;
    22 }
    23 
    24 void work(){
    25     while(x){
    26         if(x&1){
    27             for(int i=1;i<=n;i++)
    28                 b[i]=did(i,d);
    29             for(int i=1;i<=n;i++)
    30                 a[i]=b[i];            
    31         }
    32         x>>=1;d<<=1;
    33     }
    34 }
    35 
    36 int main(){
    37     scanf("%d%lld",&n,&x);n<<=1;
    38     for(int i=1;i<=n;i+=2){
    39         scanf("%d",&a[i]);
    40     }
    41     work();
    42     for(int i=1;i<n;i++){
    43         printf("%d ",a[i]);
    44     }printf("%d",a[n]);
    45 } 
    View Code

    【总结】

    然后看见我的注释没,我就在那里卡了很久,因为我最开始的L是(pos-dis+n)%n;

    然后光荣爆炸,毕竟,我没算到pos-dis的绝对值可能是小于n的啊

    所以那个位置的正确写法((pos-dis)%n+n)%n;

  • 相关阅读:
    FTP使用
    调用EJB的一点体会
    配置WEBLOGIC81连接缓冲池,提示JDBC类不在类路径的解决办法
    加载cab文件,有时候加载不上去,解决办法
    在SPS中无缝集成重设文档库下拉菜单
    statusful sessionbean 设置,不出现passivate 的问题,解决心得
    在IE耗时操作中加入进度条或进度框
    STS文档库的事件跟踪不能生效的解决办法
    学习新技术的一点体会
    在weblogic81中使用连接缓冲池成功
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7794345.html
Copyright © 2020-2023  润新知