求助(站外题)
  • 板块学术版
  • 楼主爱喝敌敌畏
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/5/20 22:19
  • 上次更新2023/11/4 23:01:07
查看原帖
求助(站外题)
65602
爱喝敌敌畏楼主2021/5/20 22:19

https://acm.timus.ru/problem.aspx?space=1&num=1977

这道题目疯狂在第10个点WA,真的不知道为什么了QAQ。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define N 100010
#define NN 300010
#define NNN 600010
#define NNNN 1200010
using namespace std;
const double eps=1e-6;
double p;//每次增加的能量 
int be[NNN]/*表示所保存的右边界*/;
struct node
{
	int lc,rc;
	double sum,l1,l2;//给一个区间打上同意的d 
	bool l3;
}tr[NNNN];int len;
inline double n2(int k)
{
	return (double)k*1.0*(k+1)/2;
}
inline void pushl1(int x,double k,int d){tr[x].sum+=d*k;tr[x].l1+=k;}
inline void pushl2(int x,double k,int d)
{
	tr[x].sum+=n2(d)*k;tr[x].l2+=k;
}
inline void pushl3(int x){tr[x].l3=1;tr[x].l1=tr[x].l2=tr[x].sum=0;}
inline void pushdown(int x,int d1,int d2)
{
	if(tr[x].l3==1)
	{
		pushl3(tr[x].lc);pushl3(tr[x].rc);
		tr[x].l3=0;
	}
	if(fabs(tr[x].l1)>eps)
	{
		pushl1(tr[x].lc,tr[x].l1,d1);pushl1(tr[x].rc,tr[x].l1,d2);
		tr[x].l1=0;
	}
	if(fabs(tr[x].l2)>eps)
	{
		pushl2(tr[x].lc,tr[x].l2,d1);pushl2(tr[x].rc,tr[x].l2,d2);pushl1(tr[x].rc,tr[x].l2*d1,d2);
		tr[x].l2=0;
	}
}
inline void updata(int x){tr[x].sum=tr[tr[x].lc].sum+tr[tr[x].rc].sum;}
inline int tong(int l,int r){return be[r]-be[l-1];}
void bt(int l,int r)
{
	int x=++len;
	if(l<r)
	{
		int mid=(l+r)>>1;
		tr[x].lc=len+1;bt(l,mid);
		tr[x].rc=len+1;bt(mid+1,r);
	}
}
void change1(int x,int l,int r,int ll,int rr,double k1,double k2)//两个标记一起下放 
{
	if(rr<ll)return ;
	if(l==ll && r==rr)
	{
		pushl1(x,k1,tong(l,r));pushl2(x,k2,tong(l,r));return ;
	}
	int mid=(l+r)>>1;pushdown(x,tong(l,mid),tong(mid+1,r));
	if(rr<=mid)change1(tr[x].lc,l,mid,ll,rr,k1,k2);
	else if(mid<ll)change1(tr[x].rc,mid+1,r,ll,rr,k1,k2);
	else
	{
		change1(tr[x].lc,l,mid,ll,mid,k1,k2);
		change1(tr[x].rc,mid+1,r,mid+1,rr,k1+tong(ll,mid)*k2,k2);
	}
	updata(x);
}
void change2(int x,int l,int r,int ll,int rr)
{
	if(rr<ll)return ;
	if(l==ll && r==rr){pushl3(x);return ;}
	int mid=(l+r)>>1;pushdown(x,tong(l,mid),tong(mid+1,r));
	if(rr<=mid)change2(tr[x].lc,l,mid,ll,rr);
	else if(mid<ll)change2(tr[x].rc,mid+1,r,ll,rr);
	else change2(tr[x].lc,l,mid,ll,mid),change2(tr[x].rc,mid+1,r,mid+1,rr);
	updata(x);
}
double findans(int x,int l,int r,int ll,int rr)//找到这个区间的和 
{
	if(l==ll && r==rr)return tr[x].sum;
	int mid=(l+r)>>1;pushdown(x,tong(l,mid),tong(mid+1,r));
	if(rr<=mid)return findans(tr[x].lc,l,mid,ll,rr);
	else if(mid<ll)return findans(tr[x].rc,mid+1,r,ll,rr);
	else return findans(tr[x].lc,l,mid,ll,mid)+findans(tr[x].rc,mid+1,r,mid+1,rr);
}
struct Query
{
	int x,y,z/*-1表示保存,大于0则表示中点*/,tim/*-表示保存,+表示操作*/;
}qu[N];
int *li[NN];int top,cnt;
inline bool cmp(int *x,int *y){return (*x)<(*y);}
int n,m;
double ener;
char st[20];
int main()
{
	scanf("%d%lf",&n,&p);
	scanf("%d",&m);
	li[top=1]=&n;cnt=0;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%s%d%d",&qu[i].tim,st+1,&qu[i].x,&qu[i].y);
		if(st[1]=='s')qu[i].z=-1;
		else
		{
			int l=qu[i].x-qu[i].y+1,r=qu[i].x+qu[i].y-1;
			qu[i].z=qu[i].x;qu[i].x=l;qu[i].y=r;
			li[++top]=&qu[i].z;
		}
		li[++top]=&qu[i].x;li[++top]=&qu[i].y;
	}
	sort(li+1,li+top+1,cmp);
	cnt=0;be[0]=0;
	for(int i=1;i<=top;i++)
	{
		if(*li[i]>be[cnt])
		{
			if(*li[i]==be[cnt]+1)be[cnt+1]=be[cnt]+1,cnt++;
			else be[cnt+1]=*li[i]-1,be[cnt+2]=*li[i],cnt+=2;
		}
		*li[i]=cnt;
	}
	bt(1,cnt);
	for(int i=1;i<=m;i++)
	{
		change1(1,1,cnt,1,cnt,(qu[i].tim-qu[i-1].tim)*p,0);
		if(qu[i].z==-1)
		{
			int l=qu[i].x,r=qu[i].y;
			ener+=findans(1,1,cnt,l,r);
			change2(1,1,cnt,l,r);
			printf("%.6lf\n",ener);
		}
		else
		{
			int l=qu[i].x,r=qu[i].y,mid=qu[i].z;double d=tong(l,mid);
			double x=ener/(d*d);ener=0;
			change1(1,1,cnt,l,mid,0,x);change1(1,1,cnt,mid+1,r,d*x,-x);
		}
	}
	return 0;
}
2021/5/20 22:19
加载中...