2018 CCPC 吉林站 H Lovers

2018 CCPC 吉林站 H Lovers

传送门:https://www.spoj.com/problems/LIS2/en/

题意:

q次操作

1.将第l~r个数的左边和和右边都加上一个数d, 使得这个数变成 \(ds_id\)的形式

2.询问区间和

题解:

线段树题

这个update操作不好维护,我们来冷静分析一下

对于一个数x,他的长度为len,我们在他后面加上一个数d,那么他的长度就变成了len+1,这个数x就变成了\(x*10+d\)

同理,在前面加上一个数,这个数x就变成了\(d*10^{len(x)}+x\)

那么对于每次的update操作,我们需要更新,区间长度,区间和,左右添加的数,右边的标记每次要*10+d,左边的标记每次要加上len*val

下推标记时

要更新区间和,区间长度,左右标记,10的幂标记

注意取模问题

代码:

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
LL sum1[maxn << 2];
LL sum2[maxn << 2];
LL lazy1[maxn << 2];
LL lazy2[maxn << 2];
LL lazylen[maxn << 2];
void push_up(int rt) {
    sum1[rt] = (sum1[ls] + sum1[rs]) % mod;
    sum2[rt] = (sum2[ls] + sum2[rs]) % mod;
}
void build(int l, int r, int rt) {
    lazy1[rt] = lazy2[rt] = 0;
    lazylen[rt] = 1;
    sum1[rt] = r - l + 1;
    sum2[rt] = 0;
    if(l == r) return;
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
    push_up(rt);
}
void push_down(int l, int r, int rt) {
    if(lazylen[rt] > 1) {
        int mid = (l + r) >> 1;

        sum2[ls] = (lazy1[rt] % mod * sum1[ls] % mod * lazylen[rt] % mod +
                    sum2[ls] % mod * lazylen[rt] % mod +
                    lazy2[rt] % mod * 1LL * (mid - l + 1) % mod) % mod;
        sum2[rs] = (lazy1[rt] % mod * sum1[rs] % mod * lazylen[rt] % mod +
                    sum2[rs] % mod * lazylen[rt] % mod +
                    lazy2[rt] % mod * 1LL * (r - mid) % mod) % mod;

        sum1[ls] = (sum1[ls] % mod * lazylen[rt] % mod * lazylen[rt] % mod) % mod;
        sum1[rs] = (sum1[rs] % mod * lazylen[rt] % mod * lazylen[rt] % mod) % mod;

        lazy1[ls] = (lazy1[rt] % mod * lazylen[ls] % mod + lazy1[ls] % mod) % mod;
        lazy1[rs] = (lazy1[rt] % mod * lazylen[rs] % mod + lazy1[rs] % mod) % mod;

        lazy2[ls] = (lazy2[ls] % mod * lazylen[rt] % mod + lazy2[rt] % mod) % mod;
        lazy2[rs] = (lazy2[rs] % mod * lazylen[rt] % mod + lazy2[rt] % mod) % mod;

        lazylen[ls] = (lazylen[ls] % mod * lazylen[rt] % mod) % mod;
        lazylen[rs] = (lazylen[rs] % mod * lazylen[rt] % mod) % mod;

        lazylen[rt] = 1;
        lazy1[rt] = 0;
        lazy2[rt] = 0;
    }
}
void update(int L, int R, int val, int l, int r, int rt) {
    if(L <= l && r <= R) {
        sum2[rt] = (val % mod * sum1[rt] % mod * 10 % mod + sum2[rt] % mod * 10 % mod + (r - l + 1) % mod * val % mod) % mod;
        sum1[rt] = (sum1[rt] % mod * 100) % mod;
        lazy1[rt] = (lazylen[rt] % mod * val % mod + lazy1[rt] % mod) % mod;
        lazy2[rt] = (lazy2[rt] % mod * 10 % mod + val % mod) % mod;
        lazylen[rt] = (lazylen[rt] * 10) % mod;
        return;
    }
    int mid = (l + r) >> 1;
    push_down(l, r, rt);
    if(L <= mid) update(L, R, val, lson);
    if(R > mid) update(L, R, val, rson);
    push_up(rt);
}
LL query(int L, int R, int l, int r, int rt) {
    if(L <= l && r <= R) {
        return sum2[rt];
    }
    int mid = (l + r) >> 1;
    push_down(l, r, rt);
    LL ans = 0;
    if(L <= mid) ans = (ans + query(L, R, lson)) % mod;
    if(R > mid) ans = (ans + query(L, R, rson)) % mod;
    return ans % mod;
}
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    int T;
    int cas = 1;
    scanf("%d", &T);
    while(T--) {
        int n, m;
        scanf("%d%d", &n, &m);
        build(1, n, 1);
        printf("Case %d:\n", cas++);
        while(m--) {
            char op[10];
            scanf("%s", op);
            if(op[0] == 'w') {
                int l, r, d;
                scanf("%d%d%d", &l, &r, &d);
                update(l, r, d, 1, n, 1);
                // debug2(n,m);
            } else {
                int l, r;
                scanf("%d%d", &l, &r);
                printf("%lld\n", query(l, r, 1, n, 1) % mod);
            }
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/buerdepepeqi/p/11196394.html

时间: 2024-08-30 07:31:58

2018 CCPC 吉林站 H Lovers的相关文章

2018 CCPC 桂林站(upc复现赛)总结

比赛一开始盯上了A题和G题,一个小时过去了还没有出题,心里有些乱.这时我看D题很多人过了,于是宝儿去看D题,说D题简单,转化成二进制暴力,于是就去做了.写的时候好像思路有点卡,WA了一发,后来马上发现问题就A了:这时大概快2个小时了.看了一眼榜单,发现除了D以外,G,H,J做的人最多:然后去看了H和J的题目,H是一道有关字符串的模拟,J是一道博弈的题目.H一开始感觉很简单,敲完后发现L随手写的样例过不去,然后越想越发现要考虑的情况很多,就先搁置继续考虑G了:J题一开始漏看了句子读错了题意,等到还

The Tower(HDU6559+2018年吉林站+数学)

题目链接 传送门 题意 告诉你圆锥的底部圆的半径和圆锥的高,再给你一个点的坐标及其运动向量,问你这个点什么时候会与这个圆锥相撞. 思路 比赛场上二分一直没过但是有人二分过了,今天再写这题想再试下二分,最后发现了自己的问题所在(可能这个点在\(check\)的时候已经穿过圆锥但是我的代码会把它当成还没达到,所以就会使得\(lb=mid\)).最后按照公式求解过了. 圆锥表面方程为 \[ \begin{aligned} \begin{cases} \frac{h-z}{h}=\frac{R}{r}\

2018 CCPC网络赛

2018 CCPC网络赛 Buy and Resell 题目描述:有一种物品,在\(n\)个地点的价格为\(a_i\),现在一次经过这\(n\)个地点,在每个地点可以买一个这样的物品,也可以卖出一个物品,问最终赚的钱的最大值. solution 用两个堆来维护,一个堆维护已经找到卖家的,一个堆维护还没找到卖家的. 对于第\(i\)个地点,在已经找到卖家的堆里找出卖的钱的最小值,如果最小值小于\(a_i\),则将卖家换成\(i\),然后将原来的卖家放到没找到卖家的那里:如果最小值对于\(a_i\)

2018 CCPC Girl Contest

Time:2018.6.3 Link A 题意 给一个长度为n的序列,有m个询问,每个询问三个数 l,r,d,问a[l] ×a[l+1]×.....×a[r],是否为d的倍数  (n<=1e5,1<=l<=r<=n,a[i]<=1e5 ,d<=1e5 ) 分析 对每个数分解质因数,维护一个前缀质因数和,对于每次询问,查询区间[l,r]的质因数是否全部含有d的质因数即可 时间复杂度O(T*nlogn) 2018 CCPC Girl Contest 原文地址:https:/

2018徐州网络赛H. Ryuji doesn&#39;t want to study

题目链接: https://nanti.jisuanke.com/t/31458 题解: 建立两个树状数组,第一个是,a[1]*n+a[2]*(n-1)....+a[n]*1;第二个是正常的a[1],a[2],a[3]...a[n] #include "bits/stdc++.h" using namespace std; #define ll long long const int MAXN=1e5+10; ll sum[MAXN],ans[MAXN]; ll num[MAXN];

ACM-ICPC 2018徐州网络赛-H题 Ryuji doesn&#39;t want to study

C*M....死于update的一个long long写成int了 心累 不想写过程了 ******** 树状数组,一个平的一个斜着的,怎么斜都行 题库链接:https://nanti.jisuanke.com/t/31460 #include <iostream> #include <cstring> #define ll long long #define lowbit(x) (x & -x) using namespace std; const int maxn =

HDU 6240 Server(2017 CCPC哈尔滨站 K题,01分数规划 + 树状数组优化DP)

题目链接  2017 CCPC Harbin Problem K 题意  给定若干物品,每个物品可以覆盖一个区间.现在要覆盖区间$[1, t]$. 求选出来的物品的$\frac{∑a_{i}}{∑b_{i}}$的最小值. 首先二分答案,那么每个物品的权值就变成了$x * b_{i} - a_{i}$ 在判断的时候先把那些权值为正的物品全部选出来, 然后记录一下从$1$开始可以覆盖到的最右端点的位置. 接下来开始DP,按照区间的端点升序排序(左端点第一关键字,右端点第二关键字) 问题转化为能否用剩

2018 徐州网络赛 H

Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i]. Unfortunately, the longer he learns, the fewer he gets. That means, if he reads books from ll to rr, he will get a

2017中国大学生程序设计竞赛-哈尔滨站 H - A Simple Stone Game

A Simple Stone Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1526    Accepted Submission(s): 346 Problem Description After he has learned how to play Nim game, Bob begins to try another