• luogu P4231 三步必杀


    嘟嘟嘟

    这道题就是区间加一个等差数列,然后最后求每一个数的值。

    O(n)做法:二阶差分。

    其实就是差分两遍。举个例子 0 0 0 0 0 0 0,变成了 0 2 4 6 8 0 0。第一遍差分:0 2 2 2 2 -8 0,然后在这个差分数组上在进行差分,得到 0 2 0 0 0 10 8,完事。

    我们在用通项搞一遍:等差数列的首项是s,末项是e,公差是d,则

    最终的样子:0  s  s+d  s+2d  e  0      0,

    第一遍差分:0  s  d      d        d  -e     0,

    第二遍差分:0  s  d-s   0        0  -e-d  e 。

    所以我们只用维护四个值就行了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 1e7 + 5;
    21 inline ll read()
    22 {
    23     ll ans = 0;
    24     char ch = getchar(), last = ' ';
    25     while(!isdigit(ch)) {last = ch; ch = getchar();}
    26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    27     if(last == '-') ans = -ans;
    28     return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32     if(x < 0) x = -x, putchar('-');
    33     if(x >= 10) write(x / 10);
    34     putchar(x % 10 + '0');
    35 }
    36 
    37 int n, m;
    38 ll dif[maxn], sum = 0, Max = -INF;
    39 
    40 int main()
    41 {
    42     n = read(); m = read();
    43     for(int i = 1; i <= m; ++i)
    44     {
    45         int L = read(), R = read(), s = read(), e = read();
    46         int d = (e - s) / (R - L);
    47         dif[L] += s; dif[L + 1] += d - s;
    48         dif[R + 1] -= e + d; dif[R + 2] += e;
    49     }
    50     for(int i = 1; i <= n; ++i) dif[i] = dif[i - 1] + dif[i];
    51     for(int i = 1; i <= n; ++i)
    52     {
    53         dif[i] = dif[i - 1] + dif[i];
    54         sum ^= dif[i];
    55         Max = max(Max, dif[i]);
    56     }
    57     write(sum); space; write(Max); enter;
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    重庆(四川)方言汇总(北方人到重庆可以先看看)
    将权限授予文件夹和程序集
    通过2009年12月5日PMP考试纪念一下
    在奥运开幕式上,日本代表队拿着太阳旗和五星红旗什么意思?大家讨论一下
    身份证号码
    Android学习笔记系列
    ActiveMQ学习:Hello ActiveMQ
    Android学习笔记(5):Hello Service
    Android学习笔记(4):Activity生命周期
    Android学习笔记(2):Hello world
  • 原文地址:https://www.cnblogs.com/mrclr/p/9744883.html
Copyright © 2020-2023  润新知