线段树恶心题
这是一道蓝桥杯的题目:
题目的意思是:
给出一个长度为 n 的数组 {A_i},由 1 到 n 标号 , 你需要维护 m 个操作。
操作分为三种,输入格式为:
1 l r d,将数组中下标 l 到 r 的位置都加上 d,即对于 l<=i<=r,执行A_i=A_i+d。
2 l_1 r_1 l_2 r_2,将数组中下标为 l_1 到 r_1 的位置,赋值成 l_2 到 r_2 的值,保证 r_1-l_1=r_2-l_2。
换句话说先对 0<=i<=r_2-l_2 执行 B_i=A_(l_2+i),再对 0<=i<=r_1-l_1 执行 A_(l_1+i)=B_i,其中 {B_i} 为一个临时数组。
3 l r,求数组中下标 l 到 r 的位置的和,即求出 ∑_(i=l到r) A_i 。
想也没想就写了线段树结果t掉 过滤40的样例 对于第二种操作我用的暴力,不知道怎么可以巧妙解出来,,
code:
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 typedef unsigned long long LL; 5 const int MAX_N=1e5+10; 6 7 struct node{ 8 LL sum; 9 int l; 10 int r; 11 LL lazy; 12 }nodes[4*MAX_N]; 13 14 // LL nums[MAX_N]; 15 16 inline int read(){ 17 int s=0,w=1; 18 char ch=getchar(); 19 while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} 20 while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); 21 return s*w; 22 } 23 24 25 26 void build(int root,int l,int r){ 27 if(l==r){ 28 nodes[root].l=l; 29 nodes[root].r=r; 30 nodes[root].lazy=0; 31 nodes[root].sum=read(); 32 return ; 33 } 34 nodes[root].l=l; 35 nodes[root].r=r; 36 nodes[root].lazy=0; 37 int mid=(l+r)>>1; 38 build(root<<1,l,mid); 39 build(root<<1|1,mid+1,r); 40 nodes[root].sum=nodes[root<<1].sum+nodes[root<<1|1].sum; 41 } 42 43 void push_down(int root){ 44 if(nodes[root].lazy>0){ 45 nodes[root<<1].lazy+=nodes[root].lazy; 46 nodes[root<<1].sum+=(nodes[root<<1].r-nodes[root<<1].l+1)*nodes[root].lazy; 47 nodes[root<<1|1].lazy+=nodes[root].lazy; 48 nodes[root<<1|1].sum+=(nodes[root<<1|1].r-nodes[root<<1|1].l+1)*nodes[root].lazy; 49 nodes[root].lazy=0; 50 } 51 } 52 53 void add(int rt,int l,int r,int al,int ar,LL val){ 54 if(l>=al&&r<=ar){ 55 nodes[rt].lazy+=val; 56 nodes[rt].sum+=(r-l+1)*val; 57 return ; 58 } 59 push_down(rt); 60 int mid=l+r>>1; 61 if(mid>=al)add(rt<<1,l,mid,al,ar,val); 62 if(mid+1<=ar)add(rt<<1|1,mid+1,r,al,ar,val); 63 nodes[rt].sum=nodes[rt<<1].sum+nodes[rt<<1|1].sum; 64 } 65 66 67 68 LL query(int rt,int l,int r,int ql,int qr){ 69 if(l>=ql&&r<=qr){ 70 return nodes[rt].sum; 71 } 72 push_down(rt); 73 int mid=l+r>>1; 74 LL left=0,right=0; 75 if(mid>=ql)left=query(rt<<1,l,mid,ql,qr); 76 if(mid+1<=qr)right=query(rt<<1|1,mid+1,r,ql,qr); 77 return left+right; 78 } 79 80 void modify(int rt,int l,int r,int idx,LL val){ 81 if(l==r){ 82 nodes[rt].sum=val; 83 return ; 84 } 85 push_down(rt); 86 int mid=l+r>>1; 87 if(mid>=idx)modify(rt<<1,l,mid,idx,val); 88 if(mid<idx)modify(rt<<1|1,mid+1,r,idx,val); 89 nodes[rt].sum=nodes[rt<<1].sum+nodes[rt<<1|1].sum; 90 } 91 92 93 int main(){ 94 ios::sync_with_stdio(false); 95 int c; 96 c=read(); 97 int n,m; 98 n=read(); 99 m=read(); 100 // for(int i=1;i<=n;i++){ 101 // nums[i]=read(); 102 // } 103 build(1,1,n); 104 while(m--){ 105 int t; 106 t=read(); 107 if(t==1){ 108 int l,r; 109 LL d; 110 l=read(); 111 r=read(); 112 d=read(); 113 add(1,1,n,l,r,d); 114 } 115 else if(t==3){ 116 int l,r; 117 l=read(); 118 r=read(); 119 printf("%lld\n",query(1,1,n,l,r)); 120 } 121 else { 122 int l1,r1,l2,r2; 123 l1=read(); 124 r1=read(); 125 l2=read(); 126 r2=read(); 127 if(l1==l2)continue; 128 vector<LL> tem; 129 for(int i=l2;i<=r2;i++){ 130 LL d = query(1,1,n,i,i); 131 tem.push_back(d); 132 } 133 for(int i=0;i<tem.size();i++){ 134 modify(1,1,n,l1+i,tem[i]); 135 } 136 } 137 } 138 return 0; 139 }

浙公网安备 33010602011771号