C. Appleman and a Sheet of Paper
Time limit per test
2 seconds
Memory limit per test
Megabytes
Appleman has a very big sheet of paper. This sheet have a form of rectangle with dimensions 1x n. Your task is help Appleman with folding of such a sheet. Actually, need to perform Q queries. Each query would have one of the following types:
- Fold the sheet of paper at position pI. After this query, the leftmost part of the paper with dimensions 1x pI must is above the rightmost part of the paper with dimensions 1x ([ current width of sheet]- pi).
- Count What's the total width of the paper pieces, if we'll make a described later cuts and consider only the pieces B Etween the cuts. We'll make one cut at distance li from the border of the current sheet of paper and the other At distance Ri from the left border of the current sheet of paper.
The explanation of the first Test example for better understanding of the problem.
Input
The first line contains the integers: n and q (1≤ n ≤ 105; 1≤ Q ≤105)-the width Of the paper and the number of queries.
Each of the following Q lines contains one of the described queries in the following format:
- "1 Pi" (1≤ pi < [ current width of sheet ])-the first type query.
- "2 lI ri" (0≤ L < ri ≤[< C22>current width of sheet])-the second type query.
Output
For each query of the second type, output the answer.
Sample Test (s)
Input
7 4
1 3
1 2
2 0 1
2 1 2
Output
4
3
Input
10 9
2 2 9
1 1
2 0 1
1 8
2 0 8
1 2
2 1 3
1 4
2 2 4
Output
7
2
10
4
5
Test instructions: give you a piece of 1*n of paper, there are 2 kinds of operation: (1) 1 x, the left half is folded to the left in the X place. (2) 2 x y sum of paper thickness for [x, Y] Interval
Idea: Actually is a simulation problem, because the range of N, and multiple seek interval and, obviously should use the tree-like array. The folded pieces of paper will become smaller during the folding process. The length of the cover on the 1-n line is also decreasing, and each time it is folded it will have some useless intervals (imagine not having to move the paper forward to 0, just keep folding), so when the past is folded, it exceeds the current right edge. can be equivalent to the right of the left fold, the equivalent of flipping one time ... (cannot be folded to the left because the excess part will be added to the thickness of the unused interval) the next time the folding operation is considered as the starting end on the right side. You can set the tag: 2 flips back to normal appearance
Code: (Refer to someone else's):
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace Std;
typedef long Long LL;
const int MAXN = 100005;
int BIT[MAXN];
int n, q;
int lowbit (int x)
{
return x &-X;
}
void Add (int x, int y)
{
while (x <= N)
{
Bit[x] + = y;
x + = Lowbit (x);
}
}
int getsum (int x)
{
int ans = 0;
while (x > 0)
{
Ans + = bit[x];
X-= Lowbit (x);
}
return ans;
}
int main ()
{
int T, p, x, y;
scanf ("%d%d", &n, &q);
memset (bit, 0, sizeof (bit));
for (int i = 1; I <= n; i++) Add (i, 1);
BOOL flag = 0;
int L = 1, r = N;
for (int i = 0; i < Q; i++)
{
scanf ("%d", &t);
if (t = = 1)
{
scanf ("%d", &p);
if (!flag) p = l + p;//recalculate origami points based on whether the paper is flipped with normal
else P = r-p + 1;
if (2 * p > R + L + 1)//Right half small, stacked to the left
{
for (int j = p; j <= R; j + +)
{
int u = getsum (j)-Getsum (j-1);//subscript starts at 0 minus 1 when processing a tree array. The same
Add (2 * p-j-1, u);
}
R = p-1;
if (flag = = 0) flag ^= 1;
}
Else
{
for (int j = l; j < P; j + +)
{
int u = getsum (j)-Getsum (j-1);
Add (2 * p-1-J, u);
}
L = p;
if (flag = = 1) flag ^= 1;
}
}
Else
{
scanf ("%d%d", &x, &y);
if (!flag)
{
x = L + x-1;
y = l + y-1;
}
Else
{
int t = x;
x = r-y;
y = r-t;
}
printf ("%d\n", Getsum (Y)-getsum (x));
}
}
return 0;
}
The following is a similar, but also omit the tag: only see the relationship between L and R to determine if the last
#include <cstdio>
#include <stdlib.h>
#include <algorithm>
using namespace Std;
#define REP (I,n) for ((i) =0; (i) < (int) (n);(i) + +)
int tree[1<<20];
void Add (int pos, int val)
{
for (int i = pos; i< (1<<20); i = ((i) | (i + 1))) Tree[i] + = val;
}
int sum (int pos)
{
int ans = 0;
for (int i = pos; i>0; i = ((i) & (i-1))) ans + = tree[i-1];
return ans;
}
int get (int x)
{
return sum (x + 1)-sum (x);
}
void update (int x, int val)
{
Add (x, Val);
}
int sum (int L, int R)
{
return sum (R)-sum (L);
}
int main ()
{
int N, Q, I, J;
scanf ("%d%d", &n, &q);
int L = 0, R = N;
REP (i, N) update (I, 1);
REP (J, Q)
{
int type;
scanf ("%d", &type);
if (type = = 1)
{
int p;
scanf ("%d", &p);
int M;
if (L < R) M = L + p;
else M = l-p;
if (L > R) Swap (L, R);
int w = min (m-l, r-m);
int L2, R2;
if (m-l <= r-m)
{
REP (i, W)
{
int tmp = GET (M-1-i);
Update (M + i, TMP);
}
L2 = M;
R2 = R;
}
Else
{
REP (i, W)
{
int tmp = GET (M + i);
Update (M-1-I, TMP);
}
L2 = M;
R2 = L;
}
L = L2;
R = R2;
}
Else
{
int L, R;
scanf ("%d%d", &l, &r);
int ans = 0;
if (L < R) ans = SUM (l + L, L + R);
else ans = SUM (l-r, l-l);
printf ("%d\n", ans);
}
}
}
461C. Appleman and a Sheet of Paper (tree-like array)