ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1011 外挂 线段树 数学思维

2022-08-08 21:32:38  阅读:338  来源: 互联网

标签:外挂 int s2 线段 tr ur ul 1011 s1


 链接:https://ac.nowcoder.com/acm/contest/26896/1011
来源:牛客网

题目描述

我的就是我的,你也是我的,记住了,狐狸!                                                                       ——韩信-白龙吟
对于打赌输了的小T会遭受到制裁,小s修改了数据库使他可以派出许多军队来围攻小T.
很不幸,小T与小s打赌打输了,现在小T遭受着枪林弹雨与十面埋伏,因为小T是神所以他决定要扭转局势。
他要修改数据库!
数据总库的信号墙有n个电极插头,每个插头有一个信号aia_iai​,
小T可以使在区间[ l,r ][\ l,r\ ][ l,r ]内的所有信号加上一个值k。
对于区间[ l,r ][\ l,r\ ][ l,r ]的信号强度有一个计算公式:
我们定义 f(k)=ak×∑j=k+1rajf(k)=a_k \times \sum_{j=k+1}^r a_jf(k)=ak​×∑j=k+1r​aj​
则信号强度就为: ∑i=lrf(i)\sum_{i=l}^r f(i)∑i=lr​f(i)
你可以认为f(i)就是第i个插头的信号强度。
现在小T一会儿修改信号值,一会儿询问信号强度,你是数据库的管理员,为了不被小TD,所以你要告诉他信号强度是多少。

注:本系列题不按难度排序哦

输入描述:

第一行两个整数n,Q

第二行n个整数代表a

后Q行代表操作:

一操作:1 l r x1\ l\ r\ x1 l r x代表区间[ l,r ][\ l,r\ ][ l,r ]加x。

二操作:2 l r2\ l\ r2 l r代表区间询问。

输出描述:

每一行一个数字,表示对于一个二操作的答案。
示例1

输入

复制
5 2
1 2 3 4 5
1 1 2 1
2 1 2

输出

复制
6

说明

样例解释:1 1 2 1使a[1]~a[2]的值每个都加了1, 即a[1]=2, a[2]=3,所以2 1 2=a[1]*a[2]=2*3=6   保证所有二操作的答案都是在long longlong\ longlong long范围内(如果你不相信,可以写高精)。

时空限制为标程的5倍,放心卡常。

备注:

100%  1≤n,Q≤105100 \% \ \ 1 \le n,Q \le 10^5100%  1≤n,Q≤105 对于所有ai≤100a_i \le 100ai​≤100

分析

题意要求的是 a1 * a2 + a2 *a3 + a3 * a1 

由 (a1+ a2 + a3) ^ 2 = a1 ^2  + a2 ^ 2 + a3 ^ 2 + a1 * a2 * 2 + a1 * a3 * 2 + a2 * a3 * 2

所以知道区间和 t1 区间平方和t2

t1 ^ 2 = t2 + 2 *答案

答案 = ( t1 ^ 2 - t2 ) / 2

//-------------------------代码----------------------------

#define int ll
const int N = 1e5+10;
int n,m,q;

int a[N];

struct node {
    int l,r,s1,s2,la1,la2;
} tr[N * 4];

void push_up(int u) {
    tr[u].s1 = tr[tr_ul].s1 + tr[tr_ur].s1;
    tr[u].s2 = tr[tr_ul].s2 + tr[tr_ur].s2;
}

void push_down(int u) {
    if(tr[u].la1 == 0 && tr[u].la2 == 1)rt;
    int x = tr[u].la1;tr[u].la1 = 0;
    tr[tr_ul].s2 += 2 * tr[tr_ul].s1 * x + x * x * tr_len(tr_ul);
    tr[tr_ur].s2 += 2 * tr[tr_ur].s1 * x + x * x * tr_len(tr_ur);
    tr[tr_ul].s1 += tr_len(tr_ul) * x;
    tr[tr_ur].s1 += tr_len(tr_ur) * x;
    tr[tr_ul].la1 += x;tr[tr_ur].la1 += x;
}

void build(int u,int l,int r) {
    tr[u]={l,r,0,0,0};
    if(l==r){tr[u].s1=a[l];tr[u].s2=a[l]*a[l];return ;}
    int mid = l + r >> 1;
    build(tr_ul,l,mid);build(tr_ur,mid+1,r);
    push_up(u);
}

int t1,t2;
void query(int u,int l,int r) {
    if(l <= tr[u].l && tr[u].r <= r) {
        t1 += tr[u].s1;
        t2 += tr[u].s2;
        rt;
    }
    push_down(u);
    if(l <= tr_mid) query(tr_ul,l,r);
    if(tr_mid <  r) query(tr_ur,l,r);
    push_up(u);
}

void modify(int u,int l,int r,int c) {
    if(l <= tr[u].l && tr[u].r <= r) {
        tr[u].s2+=2*tr[u].s1*c+c*c*tr_len(u);
        tr[u].s1+=c*tr_len(u);
        tr[u].la1+=c;
        return ;
    }
    push_down(u);
    if(l <= tr_mid) modify(tr_ul,l,r,c);
    if(tr_mid <  r) modify(tr_ur,l,r,c);
    push_up(u);
}

void solve()
{
//    cin>>n>>m;
    cin>>n>>q;
    fo(i,1,n) cin>>a[i];
    build(1,1,n);
    fo(o,1,q) {
        int op,l,r;cin>>op>>l>>r;
        if(op == 1) {
            int x;cin>>x;
            modify(1,l,r,x);
        } else if(op == 2) {
            t1 = t2 = 0;
            query(1,l,r);
            cout<<(t1 * t1 - t2) / 2<<endl;
        }
    }
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

标签:外挂,int,s2,线段,tr,ur,ul,1011,s1
来源: https://www.cnblogs.com/er007/p/16563513.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有