BOJ 451 田田的算术题

题意:给出一个数列。有两个操作:1.将给定范围内的项按照顺序加上一个等差数列的项。2.求出给定范围的数列项的和。

思路1:区间更改和区间求和的操作,很容易想到了线段树。由于等差数列满足可加性(即对相同范围内的数进行两次操作1,可以看做一次操作1的和),所以必定可以用线段树。

代码如下:

#include <bits/stdc++.h>
 
using namespace std;
 
template<class T>
inline bool read(T &n){
    T x = 0, tmp = 1; char c = getchar();
    while ((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if (c == EOF) return false;
    if (c == '-') c = getchar(), tmp = -1;
    while (c >= '0' && c <= '9') x *= 10, x += (c - '0'), c = getchar();
    n = x*tmp;
    return true;
}
 
template <class T>
inline void write(T n) {
    if (n < 0) {
        putchar('-');
        n = -n;
    }
    int len = 0, data[20];
    while (n) {
        data[len++] = n % 10;
        n /= 10;
    }
    if (!len) data[len++] = 0;
    while (len--) putchar(data[len] + 48);
}
 
 
typedef long long LL;
 
const int MAXN = 101000;
 
long long a[MAXN];
int T, M, N, Q, l, r, x, d;
 
struct interval{
    int left, right, mid;
    long long sum, delta, x;
    bool lazy;
};
 
struct SegmentTree{
    static const int MAX = 8 * 101000;
    interval node[MAX];
 
    inline int lson(int n){ return n << 1; }
    inline int rson(int n){ return (n << 1) | 1; }
 
    void build(int l, int r, int n){
        int m = (l + r) / 2;
        node[n].left = l;
        node[n].right = r;
        node[n].mid = m;
        node[n].sum = node[n].delta = node[n].x = 0LL;
        node[n].lazy = false;
 
        if (l == r){
            node[n].sum = a[l];
            return;
        }
        build(l, m, lson(n));
        build(m + 1, r, rson(n));
        node[n].sum += node[lson(n)].sum + node[rson(n)].sum;
    }
 
    void pushdown(int n){
        if (node[n].left == node[n].right){
            node[n].lazy = false;
            return;
        }
 
        //printf("[%d %d]",node[n].left,node[n].right);
 
        int l = lson(n);
        node[l].lazy = true;
        node[l].delta += node[n].delta;
        node[l].x += node[n].x;
        long long n1 = node[n].mid - node[n].left + 1;
        node[l].sum += node[n].x * n1 + n1 * (n1 - 1) / 2 * node[n].delta;
 
        //printf("lson: %lld ",node[l].sum);
 
        int r = rson(n);
        node[r].lazy = true;
        node[r].delta += node[n].delta;
        long long a1 = node[n].x + (node[n].mid - node[n].left + 1) * node[n].delta;
        node[r].x += a1;
        long long n2 = node[n].right - node[n].mid;
        node[r].sum += a1 * n2 + n2 * (n2 - 1) / 2 * node[n].delta;
 
        //printf("rson: %lld\n",node[r].sum);
 
 
        node[n].lazy = false;
        node[n].delta = node[n].x = 0LL;
    }
    long long sum(int l, int r, int n){
        if(node[n].left == node[n].right)
            return node[n].sum;
        if(l <= node[n].left && node[n].right <= r)
            return node[n].sum;
 
        if(node[n].lazy)
            pushdown(n);
 
        long long ans = 0LL;
 
        if (l <= node[n].mid)
            ans += sum(l, r, lson(n));
        if (r > node[n].mid)
            ans += sum(l, r, rson(n));
 
        return ans;
    }
    void modify(int l, int r, long long x, long long d, int n){
        if(node[n].left == node[n].right){
            node[n].sum += x;
            return;
        }
 
        if (l <= node[n].left && node[n].right <= r){
            node[n].lazy = true;
            node[n].delta += d;
            node[n].x += x;
            long long n1 = r - l + 1;
            node[n].sum += n1 * x + n1 *(n1 - 1) / 2 * d;
 
            //printf("m: %d %d\n",l,r);
            return;
        }
        if(node[n].lazy)
            pushdown(n);
 
        long long nn = r - l + 1;
        node[n].sum += nn * x + nn * (nn - 1) / 2 * d;
 
        if (r <= node[n].mid)
            modify(l, r, x, d, lson(n));
        else if (l > node[n].mid)
            modify(l, r, x, d, rson(n));
        else{
            modify(l, node[n].mid, x, d, lson(n));
            modify(node[n].mid + 1, r, x + (node[n].mid - l + 1) * d, d, rson(n));
        }
    }
};
 
SegmentTree s;
 
 
int main(void)
{
    //freopen("input.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    read(T);
    while (T--){
        read(N), read(M);
        for (int i = 1; i <= N; ++i)
            read(a[i]);
        s.build(1, N, 1);
        for (int i = 0; i < M; ++i){
            read(Q), read(l), read(r);
            if (Q == 2)
                write(s.sum(l, r, 1)),puts("");
            else{
                read(x), read(d);
                s.modify(l, r, x, d, 1);
            }
        }
    }
    return 0;
}


思路二:由于时限是10s,可以利用复杂度为n√n的块状数组。

              每个块状数组维护整体的和,和数组内所有元素对等差数列的加减(同样具有可加性)。

              如果查询或者修改区间有部分无法完全包含在块状数组中,则暴力的求和和更改。

              注意对数组大小的选择。过大过小都不合适。

代码如下:

#include <bits/stdc++.h>
 
using namespace std;
 
template<class T>
inline bool read(T &n){
    T x = 0, tmp = 1; char c = getchar();
    while ((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if (c == EOF) return false;
    if (c == '-') c = getchar(), tmp = -1;
    while (c >= '0' && c <= '9') x *= 10, x += (c - '0'), c = getchar();
    n = x*tmp;
    return true;
}
 
template <class T>
inline void write(T n) {
    if (n < 0) {
        putchar('-');
        n = -n;
    }
    int len = 0, data[20];
    while (n) {
        data[len++] = n % 10;
        n /= 10;
    }
    if (!len) data[len++] = 0;
    while (len--) putchar(data[len] + 48);
}
 
 
const int B = 250;
const int MAX = 100100;
int T,M,N,Q;
int l,r,x,d;
 
long long a[MAX];
 
struct buc{
    long long sum;
    long long d,x;
    void clear(){
        sum = d = x = 0LL;
    }
} bucket[MAX / B];
 
long long getsum(int l, int r){
    long long ans = 0;
    while(l < r && l % B != 0){
        int id = l / B;
        int pos = l - id * B;
        ans += a[l] + bucket[id].x + pos * bucket[id].d;
        l++;
    }
    while(l < r && r % B != 0){
        r--;
        int id = r / B;
        int pos = r - id * B;
        ans += a[r] + bucket[id].x + pos * bucket[id].d;
    }
    while(l < r){
        int id = l / B;
        ans += bucket[id].sum;
        l += B;
    }
    return ans;
}
 
void update(int l,int r,long long x,long long d)
{
    int cnt = 0;
    while(l < r && l % B != 0){
        int id = l / B;
        long long aa = x + cnt * d;
        a[l] += aa;
        bucket[id].sum += aa;
        cnt++,l++;
    }
    while(l + B < r){
        int id = l / B;
        bucket[id].sum += B * (x + cnt * d) + B *(B - 1) / 2 * d ;
        bucket[id].x += x + cnt * d;
        bucket[id].d += d;
        l += B,cnt += B;
    }
    while(l < r){
        int id = l / B;
        long long aa = x + cnt * d;
        a[l] += aa;
        bucket[id].sum += aa;
        cnt++,l++;
    }
}
 
int main(void)
{
    //freopen("input.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    read(T);
    while(T--){
        read(N),read(M);
        for(int i = 0 ; i < N / B + 1; i++)
            bucket[i].clear();
        for(int i = 0 ; i< N; ++i)
            read(a[i]);
        for(int i = 0 ; i< N; ++i){
            int id = i / B;
            bucket[id].sum += a[i];
        }
        for(int i = 0; i< M; ++i){
            read(Q);
            if(Q == 2){
                read(l),read(r);
                printf("%lld\n",getsum(l-1,r));
            }
            else{
                read(l),read(r),read(x),read(d);
                update(l-1,r,(long long)x,(long long)d);
            }
        }
    }
    return 0;
}


在探索智慧旅游的新纪元中,一个集科技、创新与服务于一体的整体解决方案正悄然改变着我们的旅行方式。智慧旅游,作为智慧城市的重要分支,旨在通过新一代信息技术,如云计算、大数据、物联网等,为游客、旅游企业及政府部门提供无缝对接、高效互动的旅游体验与管理模式。这一方案不仅重新定义了旅游行业的服务标准,更开启了旅游业数字化转型的新篇章。 智慧旅游的核心在于“以人为本”,它不仅仅关注技术的革新,更注重游客体验的提升。从游前的行程规划、信息查询,到游中的智能导航、个性化导览,再到游后的心情分享、服务评价,智慧旅游通过构建“一云多屏”的服务平台,让游客在旅游的全过程中都能享受到便捷、个性化的服务。例如,游客可以通过手机APP轻松定制专属行程,利用智能语音导览深入了解景点背后的故事,甚至通过三维GIS地图实现虚拟漫游,提前感受目的地的魅力。这些创新服务不仅增强了游客的参与感和满意度,也让旅游变得更加智能化、趣味化。 此外,智慧旅游还为旅游企业和政府部门带来了前所未有的管理变革。通过大数据分析,旅游企业能够精准把握市场动态,实现旅游产品的精准营销和个性化推荐,从而提升市场竞争力。而政府部门则能利用智慧旅游平台实现对旅游资源的科学规划和精细管理,提高监管效率和质量。例如,通过实时监控和数据分析,政府可以迅速应对旅游高峰期的客流压力,有效预防景区超载,保障游客安全。同时,智慧旅游还促进了跨行业、跨部门的数据共享与协同合作,为旅游业的可持续发展奠定了坚实基础。总之,智慧旅游以其独特的魅力和无限潜力,正引领着旅游业迈向一个更加智慧、便捷、高效的新时代。
内容概要:本文详细介绍了大模型的发展现状与未来趋势,尤其聚焦于DeepSeek这一创新应用。文章首先回顾了人工智能的定义、分类及其发展历程,指出从摩尔定律到知识密度提升的转变,强调了大模型知识密度的重要性。随后,文章深入探讨了DeepSeek的发展路径及其核心价值,包括其推理模型、思维链技术的应用及局限性。此外,文章展示了DeepSeek在多个行业的应用场景,如智能客服、医疗、金融等,并分析了DeepSeek如何赋能个人发展,具体体现在公文写作、文档处理、知识搜索、论文写作等方面。最后,文章展望了大模型的发展趋势,如通用大模型与垂域大模型的协同发展,以及本地部署小模型成为主流应用渠道的趋势。 适合人群:对人工智能和大模型技术感兴趣的从业者、研究人员及希望利用DeepSeek提升工作效率的个人用户。 使用场景及目标:①了解大模型技术的最新进展和发展趋势;②掌握DeepSeek在不同领域的具体应用场景和操作方法;③学习如何通过DeepSeek提升个人在公文写作、文档处理、知识搜索、论文写作等方面的工作效率;④探索大模型在特定行业的应用潜力,如医疗、金融等领域。 其他说明:本文不仅提供了理论知识,还结合实际案例,详细介绍了DeepSeek在各个场景下的应用方式,帮助读者更好地理解和应用大模型技术。同时,文章也指出了当前大模型技术面临的挑战,如模型的局限性和数据安全问题,鼓励读者关注技术的持续改进和发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值