Wannafly挑战赛22D
题解:
维护eix的区间和,询问时输出其虚部。
我们发现给x+v,就是给eix乘eiv,那么便能区间维护了。
注意sin和cos函数有些耗时,尽量减少其调用。
代码:
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<map> 5 #include<queue> 6 #include<set> 7 #include<vector> 8 #include<cmath> 9 #include<iostream> 10 #include<complex> 11 #define MAXN 1000005 12 using namespace std; 13 typedef long long ll; 14 int a[200005]; 15 16 typedef complex<double> cd; 17 cd col[600005]; 18 struct Node{ 19 int l,r; 20 cd sum; 21 Node operator + (const Node &t)const 22 { 23 Node res; 24 25 res.l=l,res.r=t.r; 26 res.sum=sum+t.sum; 27 return res; 28 } 29 }node[600015]; 30 31 void construct(int l,int r,int k) 32 { col[k]=cd(1,0); 33 if(l==r) 34 { 35 node[k].l=node[k].r=l; 36 node[k].sum=cd(cos(a[l]),sin(a[l])); 37 return; 38 } 39 int mid=(l+r)/2; 40 construct(l,mid,2*k); 41 construct(mid+1,r,2*k+1); 42 43 node[k]=node[2*k]+node[2*k+1]; 44 45 46 } 47 void fun(int k,cd v) 48 { 49 node[k].sum*=v; 50 col[k]*=v; 51 } 52 void down(int x) 53 { 54 if(col[x]!=cd(1,0)) 55 { 56 fun(2*x,col[x]); 57 fun(2*x+1,col[x]); 58 col[x]=0; 59 } 60 } 61 62 double query(int k,int x,int y) 63 { int l=node[k].l,r=node[k].r; 64 if(x<=l&&r<=y) 65 { 66 return node[k].sum.imag(); 67 } 68 down(k); 69 int mid=(l+r)/2; 70 double a; 71 72 if(x>mid) a=query(2*k+1,x,y); 73 else if(y<=mid) a=query(2*k,x,y); 74 else a=query(2*k,x,mid)+query(2*k+1,mid+1,y); 75 76 return a; 77 78 } 79 struct Node modifiy(int k,int x,int y,cd v) 80 { int l=node[k].l,r=node[k].r; 81 if(x<=l&&r<=y) 82 { fun(k,v); 83 84 return node[k]; 85 } 86 down(k); 87 int mid=(l+r)/2; 88 89 90 if(x>mid) node[k]=node[2*k]+modifiy(2*k+1,x,y,v); 91 else if(y<=mid) node[k]=modifiy(2*k,x,y,v)+node[2*k+1]; 92 else node[k]=modifiy(2*k,x,y,v)+modifiy(2*k+1,x,y,v); 93 return node[k]; 94 } 95 ll read() 96 { 97 ll x=0,f=1;char ch=getchar(); 98 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 99 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 100 return x*f; 101 } 102 int main() 103 { 104 int n; 105 n=read(); 106 for(int i=1;i<=n;i++) 107 a[i]=read(); 108 construct(1,n,1); 109 int m; 110 cin>>m; 111 while(m--) 112 { 113 int op,l,r; 114 ll v; 115 op=read(); 116 if(op==1) 117 { l=read(),r=read(),v=read(); 118 119 modifiy(1,l,r,cd(cos(v),sin(v))); 120 } 121 else 122 { 123 l=read(),r=read(); 124 printf("%.1f\n",query(1,l,r)); 125 } 126 } 127 }