• Ynoi2012 NOIP2015洋溢着希望


    写篇博客纪念一下人生第一道(YnOI)

    不过这个题确实是不复杂

    Description

    link

    支持两种操作,区间加和区间 (sin)

    (n,m le 2 imes 10^5)

    Solution

    [Begin ]

    我们看到三角函数,还有加法

    还是比较明显地指向了和角公式

    如果不会和角公式? 这个百度应该可以 $ Get $ 到

    (sin(a+b)=sin(a) cos(b)+cos(a)sin(b))

    (cos(a+b)=cos(a)cos(b)-sin(a)sin(b))

    (sin)(cos) 的都用库里的函数就行

    我们维护一下每个点的 (sin)(cos) 就可以了吧……

    具体要这么写:

    inline void push_up(int p,double ts,double tc)
    	{
    		double s=sinn(p),c=coss(p);
    		sinn(p)=ts*c+tc*s;
    		coss(p)=tc*c-ts*s;
    		return ;
    	}
    	inline void spread(int p)
    	{
    		if(fl(p))
    		{
    			fl(p<<1)+=fl(p); fl(p<<1|1)+=fl(p);
    			double ts=sin(fl(p)),tc=cos(fl(p));
    			push_up(p<<1,ts,tc); push_up(p<<1|1,ts,tc);
    		}return fl(p)=0,void();
    	}
    

    (但是在其它函数里面是直接搞的左右和,没有用 (Push_up)

    [Q.A.D. ]

    (P.S.)博主知道是(QED)

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=2e5+10;
    	struct node{
    		int l,r,fl;
    		double sinn,coss;
    		#define fl(p) t[p].fl
    		#define l(p) t[p].l
    		#define r(p) t[p].r
    		#define sinn(p) t[p].sinn
    		#define coss(p) t[p].coss
    	}t[N<<2];
    	int n,a[N];
    	inline void build(int p,int l,int r)
    	{
    		l(p)=l; r(p)=r; 
    		if(l==r) return sinn(p)=sin(a[l]),coss(p)=cos(a[l]),void();
    		int mid=(l+r)>>1;
    		build(p<<1,l,mid); build(p<<1|1,mid+1,r);
    		sinn(p)=sinn(p<<1)+sinn(p<<1|1); coss(p)=coss(p<<1|1)+coss(p<<1);
    		return ;
    	}
    	inline void push_up(int p,double ts,double tc)
    	{
    		double s=sinn(p),c=coss(p);
    		sinn(p)=ts*c+tc*s;
    		coss(p)=tc*c-ts*s;
    		return ;
    	}
    	inline void spread(int p)
    	{
    		if(fl(p))
    		{
    			fl(p<<1)+=fl(p); fl(p<<1|1)+=fl(p);
    			double ts=sin(fl(p)),tc=cos(fl(p));
    			push_up(p<<1,ts,tc); push_up(p<<1|1,ts,tc);
    		}return fl(p)=0,void();
    	}
    	inline void change(int p,int l,int r,double sinn,double coss,int x)
    	{
    		if(l<=l(p)&&r(p)<=r) return push_up(p,sinn,coss),fl(p)+=x,void(); 
    		int mid=(l(p)+r(p))>>1; spread(p);
    		if(l<=mid) change(p<<1,l,r,sinn,coss,x);
    		if(r>mid) change(p<<1|1,l,r,sinn,coss,x);
    		sinn(p)=sinn(p<<1)+sinn(p<<1|1);
    		coss(p)=coss(p<<1|1)+coss(p<<1);
    		return ;
    	}
    	inline double ask(int p,int l,int r)
    	{
    		if(l<=l(p)&&r(p)<=r) return sinn(p);
    		spread(p);
    		int mid=(l(p)+r(p))>>1; double ans=0;
    		if(l<=mid) ans+=ask(p<<1,l,r);
    		if(r>mid) ans+=ask(p<<1|1,l,r);
    		return ans;
    	}
    	signed main()
    	{
    		n=read(); for(int i=1;i<=n;++i) a[i]=read();
    		build(1,1,n); int T=read(); 
    		while(T--)
    		{
    			int opt=read(),x=read(),y=read(),z;
    			if(opt==1) z=read(),change(1,x,y,sin(z),cos(z),z);
    			if(opt==2) printf("%.1lf
    ",ask(1,x,y));
    		}
    		return 0;
    	}
    }
    signed main(){return yspm::main();} 
    
  • 相关阅读:
    HDU 5698 瞬间移动
    HDU 5695 Gym Class
    HDU 5694 BD String
    HDU 5692 Snacks
    HDU 5691 Sitting in Line
    胜利大逃亡
    BFS(广度优先搜索)
    计算直线的交点数
    Division
    Jesse's Code
  • 原文地址:https://www.cnblogs.com/yspm/p/12515173.html
Copyright © 2020-2023  润新知