https://www.lydsy.com/JudgeOnline/problem.php?id=4597
https://www.luogu.org/problemnew/show/P4340
妄图直接暴力维护一堆东西,以直接维护题目要求的值(具体见代码...)
最后花了2个小时维护完了,A掉了,然而好像常数比别人大一倍?
上网搜题解,发现大部分东西都可以抵消掉??回想维护过程中,好像有一堆抵消掉的东西?
看来即使可以暴力维护,也还是要多观察题目性质...
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define fi first 7 #define se second 8 #define mp make_pair 9 #define pb push_back 10 typedef long long ll; 11 typedef unsigned long long ull; 12 typedef pair<ll,ll> pii; 13 const ll md=1e9+7; 14 ll n,q; 15 ll a[100100]; 16 ll pw3[100100]; 17 const ll N=400100; 18 #define lc (num<<1) 19 #define rc (num<<1|1) 20 ll d1[N],d2[N],d3[N],d4[N],d5[N]; 21 //d1:区间乘积 22 //d2:区间和 23 //d3:除了全部是乘号外,所有选择方案靠左边全是乘号一段的积的和 24 //d4:除了全部是乘号外,...靠右边...(带符号) 25 //d5:答案 26 //维护过程中发现d4必定为0... 27 /* 28 举例:1,2,3 29 1+2+3,1+2-3,1+2*3, 30 1-2+3,1-2-3,1-2*3, 31 1*2+3,1*2-3,1*2*3 32 d3应当维护1*6+1*2*2=10 33 d4应当维护3*3-3*3+2*3-2*3=0 34 */ 35 void upd(ll l,ll r,ll num) 36 { 37 d1[num]=d1[lc]*d1[rc]%md; 38 d2[num]=(d2[lc]+d2[rc])%md; 39 ll mid=l+((r-l)>>1); 40 d3[num]=(d3[lc]*pw3[r-mid]%md+d1[lc]*2*pw3[r-(mid+1)]%md 41 +d1[lc]*d3[rc]%md)%md; 42 d4[num]=(d4[rc]*pw3[mid-l+1]%md//+d1[rc]*2*pw3[mid-l]%md 43 +d1[rc]*d4[lc]%md)%md; 44 ll d4l=(d4[lc]+d1[lc])%md,d3r=(d3[rc]+d1[rc])%md; 45 /* 46 d5[num]=(2*(r-mid)*d5[lc]%md+(r-mid)*((d5[lc]-d4l+md)%md)%md 47 +(mid-l+1)*((d5[rc]-d3r+md)%md)%md 48 +d4l*d3r%md)%md; 49 */ 50 ll m=pw3[mid-l],n=pw3[r-(mid+1)]; 51 /* 52 d5[num]=(2*(r-mid)*d5[lc]%md+2*(mid-l+1)*d5[rc]%md 53 +pw3[mid-l]*(md-2)%md*d3r%md 54 +(r-mid)*((d5[lc]-d4l+md)%md)%md 55 +(mid-l+1)*((d5[rc]-d3r+md)%md)%md 56 +d4l*d3r%md)%md; 57 */ 58 d5[num]=(2*n*d5[lc]%md+2*m*d5[rc]%md 59 +m*(md-2)%md*d3r%md 60 +n*((d5[lc]-d4l+md)%md)%md 61 +m*((d5[rc]-d3r+md)%md)%md 62 +d4l*d3r%md)%md; 63 64 /* 65 d5[num]=(2*(r-mid)*d5[lc]%md+2*(mid-l+1)*d5[rc]%md 66 +pw3[mid-l]*(md-2)%md*d3r%md 67 +(r-mid)*((d5[lc]-d4l+md)%md)%md 68 + 69 printf("1t%lld %lld %lld %lld %lld %lld %lld ",l,r,d1[num],d2[num], 70 d3[num],d4[num],d5[num]); 71 printf("2t%lld %lld %lld ",(r-mid)*d5[lc]%md+(mid-l+1)*d5[rc]%md, 72 (r-mid)*d5[lc]%md+(mid-l+1)*d5[rc]%md+pw3[mid-l]*(md-2)%md*d3r%md, 73 (r-mid)*((d5[lc]-d4l+md)%md)%md 74 +(mid-l+1)*((d5[rc]-d3r+md)%md)%md 75 +d4l*d3r%md); 76 */ 77 } 78 void pre(ll l,ll num,ll x) 79 { 80 d1[num]=x; 81 d2[num]=x; 82 d3[num]=d4[num]=0; 83 d5[num]=x; 84 } 85 void build(ll l,ll r,ll num) 86 { 87 if(l==r) {pre(l,num,a[l]);return;} 88 ll mid=l+((r-l)>>1); 89 build(l,mid,lc);build(mid+1,r,rc); 90 upd(l,r,num); 91 } 92 void setx(ll L,ll x,ll l,ll r,ll num) 93 { 94 if(l==r) {pre(l,num,x);return;} 95 ll mid=l+((r-l)>>1); 96 if(L<=mid) setx(L,x,l,mid,lc); 97 else setx(L,x,mid+1,r,rc); 98 upd(l,r,num); 99 } 100 int main() 101 { 102 ll i,x,y; 103 pw3[0]=1; 104 for(i=1;i<=100000;i++) 105 pw3[i]=pw3[i-1]*3%md; 106 scanf("%lld%lld",&n,&q); 107 for(i=1;i<=n;i++) scanf("%lld",&a[i]); 108 build(1,n,1); 109 //printf("%lld %lld %lld %lld %lld",d1[1],d2[1],d3[1],d4[1],d5[1]); 110 while(q--) 111 { 112 scanf("%lld%lld",&x,&y); 113 setx(x,y,1,n,1); 114 printf("%lld ",d5[1]); 115 } 116 return 0; 117 }