「BJOI2018」链上二次求和
「BJOI2018」链上二次求和
https://loj.ac/problem/2512
我说今天上午写博客吧。怕自己写一上午,就决定先写道题。
然后我就调了一上午线段树。
花了2h找到lazy标记没有清空。我tm清空了有没有标记没清空标记本身。
又花25min找到某个乘法爆int了。int真的淡疼,要不是longlong自带巨无霸常数,这辈子都不想用int。
一个上午就没有了。
1 //Achen 2 #include<bits/stdc++.h> 3 #define For(i,a,b) for(int i=(a);i<=(b);i++) 4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--) 5 #define Formylove return 0 6 const int N=200007,p=1e9+7,inv2=5e8+4; 7 typedef long long LL; 8 typedef double db; 9 using namespace std; 10 int n,m,a[N],sum[N]; 11 12 template<typename T> void read(T &x) { 13 char ch=getchar(); T f=1; x=0; 14 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); 15 if(ch=='-') f=-1,ch=getchar(); 16 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f; 17 } 18 19 int mo(int x) { return x<0?x+p:(x>=p?x-p:x); } 20 21 int sg[N<<2],si0[N<<2],si1[N<<2],si2[N<<2]; 22 bool tg[N<<2]; 23 struct tag { 24 int a,b,c; 25 }lz[N<<2],pls; 26 tag operator +(const tag&A,const tag&B) { return (tag){mo(A.a+B.a),mo(A.b+B.b),mo(A.c+B.c)}; } 27 28 #define lc (x<<1) 29 #define rc ((x<<1)|1) 30 #define mid ((l+r)>>1) 31 void addtag(int x,tag y) { 32 //printf("%d %d %d %d\n",x,y.a,y.b,y.c); 33 sg[x]=mo(mo(mo(sg[x]+(LL)y.a*si2[x]%p)+(LL)y.b*si1[x]%p)+(LL)y.c*si0[x]%p); 34 lz[x]=lz[x]+y; tg[x]=1; 35 //printf("%d %d %d\n",lz[x].a,lz[x].b,lz[x].c); 36 } 37 38 void down(int x) { 39 if(!tg[x]) return ; 40 addtag(lc,lz[x]); 41 addtag(rc,lz[x]); 42 tg[x]=0; lz[x]=(tag){0,0,0};///////// 43 } 44 45 void build(int x,int l,int r) { 46 if(l==r) { 47 sg[x]=sum[l]; si0[x]=1; si1[x]=l; 48 si2[x]=(LL)l*l%p; return; 49 } 50 build(lc,l,mid); build(rc,mid+1,r); 51 sg[x]=mo(sg[lc]+sg[rc]); 52 si0[x]=mo(si0[lc]+si0[rc]); 53 si1[x]=mo(si1[lc]+si1[rc]); 54 si2[x]=mo(si2[lc]+si2[rc]); 55 } 56 57 void upd(int x,int l,int r,int ql,int qr) { 58 if(l>=ql&&r<=qr) { addtag(x,pls); return; } 59 down(x); 60 if(ql<=mid) upd(lc,l,mid,ql,qr); 61 if(qr>mid) upd(rc,mid+1,r,ql,qr); 62 sg[x]=mo(sg[lc]+sg[rc]); 63 } 64 65 int qry(int x,int l,int r,int ql,int qr) { 66 if(ql>qr) return 0; 67 if(l>=ql&&r<=qr) return sg[x]; 68 down(x); 69 if(qr<=mid) return qry(lc,l,mid,ql,qr); 70 if(ql>mid) return qry(rc,mid+1,r,ql,qr); 71 return mo(qry(lc,l,mid,ql,qr)+qry(rc,mid+1,r,ql,qr)); 72 } 73 74 int main() { 75 //freopen("1.in","r",stdin); 76 //freopen("1.out","w",stdout); 77 read(n); read(m); 78 For(i,1,n) { read(a[i]); sum[i]=mo(sum[i-1]+a[i]); } 79 For(i,1,n) sum[i]=mo(sum[i-1]+sum[i]); 80 build(1,1,n); 81 For(i,1,m) { 82 int o,l,r,v; 83 read(o); read(l); read(r); 84 if(o==1) { 85 read(v); if(l>r) swap(l,r); 86 int len=r-l+1,a=(LL)v*inv2%p; 87 pls=(tag){a,(LL)a*(3-2*l+p)%p,((LL)l*l-3*l+2)%p*a%p}; upd(1,1,n,l,r); 88 if(r<n) { 89 pls=(tag){0,(LL)len*v%p,((LL)len*(len+1)/2%p*v%p-(LL)len*r%p*v%p+p)%p}; 90 upd(1,1,n,r+1,n); 91 } 92 } 93 else if(o==2) { 94 LL ans=(((LL)r-l+1)*qry(1,1,n,n,n)%p-qry(1,1,n,max(1,l-1),r-1)+p-qry(1,1,n,max(1,n-r),n-l)+p)%p; 95 printf("%lld\n",ans); 96 } 97 } 98 Formylove; 99 }