Codeforces Round #263 (Div. 1) C. Appleman and a Sheet of Paper 树状数组暴力更新

C. Appleman and a Sheet of Paper

Appleman has a very big sheet of paper. This sheet has a form of rectangle with dimensions 1 × n. Your task is help Appleman with folding of such a sheet. Actually, you need to perform q queries. Each query will have one of the following types:

  1. Fold the sheet of paper at position pi. After this query the leftmost part of the paper with dimensions 1 × pi must be above the rightmost part of the paper with dimensions 1 × ([current width of sheet] - pi).
  2. Count what is the total width of the paper pieces, if we will make two described later cuts and consider only the pieces between the cuts. We will make one cut at distance li from the left border of the current sheet of paper and the other at distance ri from the left border of the current sheet of paper.

Please look at the explanation of the first test example for better understanding of the problem.

Input

The first line contains two 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 ≤ li < ri ≤ [current width of sheet]) — the second type query.
Output

For each query of the second type, output the answer.

input
7 41 31 22 0 12 1 2
output
43思路: 暴力更新, 然后用FenwickTree 或者SegmentTree进行区间求和即可。因为每个位置上的value只会更新到别的位置一次,所以暴力的话复杂度也是O(n), 然后更新的时候分两种情况, 如果折过去的长度大于右边界 就相当于把右面的对应长度折过来, 否则就是题目中所说的从左面折了。我用ua, ub,维护了当前区间的左右端点, 每次查询也分两种情况。
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 5;
 4 namespace FenwickTree {
 5 int arr[maxn];
 6 void Modify(int x, int d) {
 7     while(x < maxn) {
 8         arr[x] += d;
 9         x += x & -x;
10     }
11 }
12 void init(int n) {
13     memset(arr, 0, sizeof arr);
14     for(int i = 1; i <= n; i++) {
15         Modify(i, 1);
16     }
17 }
18 int query(int x) {
19     int res = 0;
20     while (x > 0) {
21         res += arr[x];
22         x -= x & -x;
23     }
24     return res;
25 }
26 }
27 int main() {
28 #ifndef ONLINE_JUDGE
29     freopen("in.txt","r",stdin);
30 #endif
31     int n, q;
32     while (~ scanf ("%d%d", &n, &q)) {
33         int tot = 0, direction = 0;
34         FenwickTree::init(n);
35         int ub = n;
36         for (int j = 0; j < q; j++) {
37             int op, l, r, p;
38             int ua = tot+1;
39             scanf ("%d", &op);
40             if (op == 1) {
41                 scanf ("%d", &p);
42                 if (!direction) {
43                     if (2*p <= 1 + ub - ua) {
44                         for (int i = ua; i <= ua+p-1; i++) {
45                             FenwickTree::Modify(2*ua+2*p-i-1, FenwickTree::query(i) - FenwickTree::query(i-1));
46                         }
47                         tot += p;
48                     } else {
49                         p = ub - (ua + p-1);
50                         for (int i = ub; i >= ub-p+1; i--) {
51                             FenwickTree::Modify(2*ub-2*p+1-i, FenwickTree::query(i) - FenwickTree::query(i-1));
52                         }
53                         ub = ub - p;
54                         direction ^= 1;
55                     }
56                 }else{
57                     if (2*p > 1 + ub - ua){
58                         p = ub - (ua + p-1);
59                         for (int i = ua; i <= ua+p-1; i++) {
60                             FenwickTree::Modify(2*ua+2*p-i-1, FenwickTree::query(i) - FenwickTree::query(i-1));
61                         }
62                         direction ^= 1;
63                         tot += p;
64                     }else{
65                         for (int i = ub; i >= ub-p+1; i--) {
66                             FenwickTree::Modify(2*ub-2*p+1-i, FenwickTree::query(i) - FenwickTree::query(i-1));
67                         }
68                         ub = ub - p;
69                     }
70                 }
71
72             } else {
73                 scanf ("%d%d", &l, &r);
74                 if (!direction) {
75                     printf("%d\n", FenwickTree::query(ua+r-1)-FenwickTree::query(ua-1+l));
76                 }else{
77                     printf("%d\n", FenwickTree::query(ub-l)-FenwickTree::query(ub-r));
78                 }
79             }
80         }
81     }
82     return 0;
83 }
 
时间: 2024-08-26 14:35:33

Codeforces Round #263 (Div. 1) C. Appleman and a Sheet of Paper 树状数组暴力更新的相关文章

Codeforces Round #263 (Div. 1) C. Appleman and a Sheet of Paper

题目地址:http://codeforces.com/contest/461/problem/C 题目大意:见原题. 算法分析:启发式暴力,每次把短的纸带折到长的纸带中,在全局记一个rev标记.注意细节. Code: #include <cstdio> #include <algorithm> #define N 100000 using namespace std; bool rev; int n,q,beg=1,end,typ,p,l,r,bit[N+10]; inline v

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida&#39;s problem (树状数组求逆序数 变形)

题目链接 题意: 给出一些数a[n],求(i, j), i<j 的数量,使得:f(1, i, a[i]) > f(j, n, a[j]) . f(lhs, rhs, x) 指在 { [lhs, rhs]范围中,a[k]的值=x } 的数量. 1.  f(1, i, a[i]) 就是指a[i]前面包括a[i]的数中,有几个值=a[i]. 2.  f(j, n, a[j]) 就是指a[j]后面包括a[j]的数中有几个值=a[j]. 虽然a[x]范围不小,但是n的范围是1000,不是很大,所以我们可

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida&#39;s problem (树状数组)

D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants her partn

Codeforces Round #365 (Div. 2) D - Mishka and Interesting sum(离线树状数组)

http://codeforces.com/contest/703/problem/D 题意: 给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和. 思路: 这儿利用一下异或和的性质,在一个区间中,我们如果把所有数字都异或的话,可以发现最后偶数次的数字异或后都变成了0,只剩下了奇数次的数字异或. 举个例子,{1,2,3,2,3,5} 异或和是1^2^3^2^3^5=1^5 因为最后要计算偶数次数字的异或和,那么最后我们只需要再异或上该区间内所有不同数字即可. 那么我们可以先

461C. Appleman and a Sheet of Paper(树状数组)

C. Appleman and a Sheet of Paper time limit per test 2 seconds memory limit per test 256 megabytes Appleman has a very big sheet of paper. This sheet has a form of rectangle with dimensions 1 × n. Your task is help Appleman with folding of such a she

贪心 Codeforces Round #263 (Div. 2) C. Appleman and Toastman

题目传送门 1 /* 2 贪心:每次把一个丢掉,选择最小的.累加求和,重复n-1次 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-1 13:20:01 7 File Name :A.cpp 8 *************************************************/ 9 10 #include <cstdio>

Codeforces Round #263 (Div.1) B. Appleman and Tree

题目地址:http://codeforces.com/contest/461/problem/B 题目大意:给一棵树.每一个点为白色或黑色.切断一些边,使得每一个连通块有且仅有一个黑点,问划分方案数. 算法讨论:TreeDP. f[x][0..1]表示x所在连通块有0/1个黑点.设y为x的儿子,则DP方程为f[x][1]=f[x][1]*f[y][0]+f[x][1]*f[y][1]+f[x][0]*f[y][1],f[x][0]=f[x][0]*f[y][0]+f[x][0]*f[y][1].

Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp

链接: http://codeforces.com/contest/462/problem/D 题意: 给定n个点的树, 0为根,下面n-1行表示每个点的父节点 最后一行n个数 表示每个点的颜色,0为白色,1为黑色. 把树分成若干个联通块使得每个联通块有且仅有一个黑点,问有多少种分法(结果mod1e9+7) 题解: 树形dp,每个点有2个状态,已经归属于某个黑点和未归属于某个黑点. 代码: 31 int n; 32 int x[MAXN]; 33 VI G[MAXN]; 34 ll dp[MAX

Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)

题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input :standard input output:standard output Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices a