求助分块过 2e5
查看原帖
求助分块过 2e5
461407
Withershine楼主2024/3/27 20:52

让同机房大佬看了一下,复杂度应该是 O(nn)O(n\sqrt{n}) 的。

#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;
}
2024/3/27 20:52
加载中...