[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\n",query(stpos+l,stpos+r));
66             else printf("%d\n",query(stpos-r,stpos-l));
67         }
68     //    printf("        rest:%d   st:%d   rev:%d\n",rest,stpos,rev);
69     //    for(i=1;i<=rest;i++)printf("  %d",get(stpos+(!rev?i-1:-i+1)));puts("");
70     }
71 }
View Code

 

posted @ 2016-10-11 20:50  czllgzmzl  阅读(254)  评论(0编辑  收藏  举报