• [51nod1502]苹果曼和纸


      苹果曼有很大的一张纸。这张纸的形状是1×n的长方形。你的任务是帮助苹果曼来折叠这一张纸。有一些操作,这些操作有如下两个种形式:
      1. 把这张纸在第pi个位置对折。经过对折后,左边的1×pi部分会盖到右边的1×([当前纸片宽度]-pi)上面。
      2. 询问在如果把距离左端li以内的剪掉,距离左端ri以外的也剪掉,那么还剩下多少纸片的长度。
      看样例,可以更好的解理这个问题。

      第一次折叠之后,纸片的宽度变成了4,第二次折叠,纸片的宽度变成了2。

     Input
      单组测试数据。
      第一行有两个整数n和q (1≤n≤10^5; 1≤q≤10^5),表示纸片的宽度和询问数目。
      接下来q行的形式是如下之一:
      · "1 pi" (1≤pi<[当前纸片宽度]) — 第一类操作。
      · "2 li ri" (0≤li<ri≤[当前纸片宽度]) — 第二类操作。
     Output
      对于第二类操作,输出答案。

     Input示例
      7 4
      1 3
      1 2
      2 0 1
      2 1 2
     Output示例
      4
      3

      维护一下每个位置上有多少层纸,每次翻折的时候,只翻较短的一部分(所以得记一下当前的方向),那么总共最多只会有n个位置被翻到别的位置上。

      主要是记方向、计算实际位置很麻烦...

      我直接分类讨论。。当前维护的是否是翻转后的、当前翻折操作是否是否会导致翻转,总共四类。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cmath>
     7 #include<cstdlib>
     8 #define ll long long
     9 #define ull unsigned long long
    10 #define ui unsigned int
    11 //#define d double
    12 #define ld long double
    13 const int maxn=100233,modd=1000000007;
    14 int t[maxn];
    15 int i,j,k,n,m;
    16 
    17 int ra,fh;char rx;
    18 inline int read(){
    19     rx=getchar(),ra=0,fh=1;
    20     while(rx<'0'&&rx!='-')rx=getchar();
    21     if(rx=='-')fh=-1,rx=getchar();
    22     while(rx>='0')ra=ra*10+rx-48,rx=getchar();return ra*fh;
    23 }
    24 
    25 inline void add(int x,int V){while(x<=n)t[x]+=V,x+=x&-x;}
    26 inline int get(int x){
    27     int sm=0,x1=x-1;
    28     while(x)sm+=t[x],x-=x&-x;
    29     while(x1)sm-=t[x1],x1-=x1&-x1;
    30     return sm;
    31 }
    32 inline int query(int l,int r){
    33     int sm=0;
    34     while(r)sm+=t[r],r-=r&-r;
    35     l--;while(l)sm-=t[l],l-=l&-l;return sm;
    36 }
    37 
    38 int main(){
    39     n=read(),m=read();register int i,j;
    40     for(i=1;i<=n;i++){t[i]++;if(i+(i&-i)<=n)t[i+(i&-i)]+=t[i];}
    41     int l,r,stpos=1,rest=n,p;bool rev=0;
    42     while(m--){
    43         if(read()==1){
    44             p=read();
    45             if((p<<1)<=rest)
    46             if(!rev){
    47                 for(i=stpos,j=stpos+(p<<1)-1;i<j;i++,j--)add(j,get(i));
    48                 stpos+=p;rest-=p;
    49             }else{
    50                 for(i=stpos-(p<<1)+1,j=stpos;i<j;i++,j--)add(i,get(j));
    51                 stpos-=p;rest-=p;
    52             }
    53             else
    54             if(!rev){
    55                 p=rest-p;
    56                 for(i=stpos+rest-1,j=i-(p<<1)+1;j<i;j++,i--)add(j,get(i));
    57                 rev=1,stpos=stpos+rest-1-p;rest-=p;
    58             }else{
    59                 p=rest-p;
    60                 for(j=stpos-rest+1,i=j+(p<<1)-1;j<i;j++,i--)add(i,get(j));
    61                 rev=0,stpos=stpos-rest+1+p;rest-=p;
    62             }
    63         }else{
    64             l=read(),r=read()-1;
    65             if(!rev)printf("%d
    ",query(stpos+l,stpos+r));
    66             else printf("%d
    ",query(stpos-r,stpos-l));
    67         }
    68     //    printf("        rest:%d   st:%d   rev:%d
    ",rest,stpos,rev);
    69     //    for(i=1;i<=rest;i++)printf("  %d",get(stpos+(!rev?i-1:-i+1)));puts("");
    70     }
    71 }
    View Code
  • 相关阅读:
    常见面试测试要点
    怎样在 CentOS/RHEL 7/6 上安装和配置 Sendmail 服务器
    Cannot uninstall 'pyparsing'. It is a distutils installed project
    Linux下校验SHA1和MD5的方法
    Linux查看进程启动时间和运行多长时间
    sqlplus -S参数表示什么意思?
    dnspython模块报错 AttributeError: 'CNAME' object has no attribute 'address'
    CentOS7中安装pip的方法
    四则运算中遇到的一个问题
    动手动脑
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5950742.html
Copyright © 2020-2023  润新知