让同机房大佬看了一下,复杂度应该是 O(nn) 的。
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#define ll long long
#define inf 0x3f3f3f3f
#define fr(i , a , b) for(ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(ll i = a ; i >= b ; --i)
using namespace std;
ll n , m , a[200001];
ll block , L[1001] , R[1001] , pos[200001] , atg[1001];
double si[200001] , co[200001] , ssi[1001] , sco[1001];
inline void build()
{
ll ql = sqrt(n * log(n));
block = n / ql;
fr(i , 1 , block)
{
L[i] = R[i - 1] + 1;
R[i] = i * block;
}
if(R[block] != n)
{
block++;
L[block] = R[block - 1] + 1;
R[block] = n;
}
fr(i , 1 , block)
{
fr(j , L[i] , R[i])
{
pos[j] = i;
si[j] = sin(a[j]);
ssi[i] += si[j];
co[j] = cos(a[j]);
sco[i] += co[j];
}
}
}
inline void updata(ll no , ll v)
{//O(1)
ll nb = pos[no];
ssi[nb] -= si[no];
sco[nb] -= co[no];
si[no] = sin(a[no]) * cos(v) + cos(a[no]) * sin(v);
co[no] = cos(a[no]) * cos(v) - sin(a[no]) * sin(v);
ssi[nb] += si[no];
sco[nb] += co[no];
a[no] += v;
}
inline void updata1(ll bl)
{
fr(i , L[bl] , R[bl])
{
updata(i , atg[bl]);
}
atg[bl] = 0;
}
inline void update(ll l , ll r , ll v)
{
ll q = pos[l] , p = pos[r];
if(q == p)
{
if(atg[q])
{
updata1(q);
}
fr(i , l , r)
{
updata(i , v);
}
return ;
}
if(atg[q])
{
updata1(q);
}
fr(i , l , R[q])
{
updata(i , v);
}
if(atg[p])
{
updata1(p);
}
fr(i , L[p] , r)
{
updata(i , v);
}
fr(i , q + 1 , p - 1)
{
atg[i] += v;
}
return ;
}
inline double ask(ll l , ll r)
{
ll q = pos[l] , p = pos[r];
double s = 0;
if(q == p)
{
if(atg[q])
{
updata1(q);
}
fr(i , l , r)
{
s += si[i];
}
return s;
}
if(atg[q])
{
updata1(q);
}
fr(i , l , R[q])
{
s += si[i];
}
if(atg[p])
{
updata1(p);
}
fr(i , L[p] , r)
{
s += si[i];
}
fr(i , q + 1 , p - 1)
{
if(atg[i])
{
s += ssi[i] * cos(atg[i]) + sco[i] * sin(atg[i]);
continue;
}
s += ssi[i];
}
return s;
}
signed main()
{
// freopen("in.in" , "r" , stdin);
// freopen("out.out" , "w" , stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
fr(i , 1 , n)
{
cin >> a[i];
}
build();
cin >> m;
while(m--)
{
ll op , l , r , v;
cin >> op;
if(op == 1)
{
cin >> l >> r >> v;
update(l , r , v);
}
else
{
cin >> l >> r;
printf("%.1lf\n" , ask(l , r));
}
}
return 0;
}