为什么我的线段树又TLE又WA
查看原帖
为什么我的线段树又TLE又WA
1163238
YWHHDJSer楼主2024/6/11 15:39

对最优解储存数组p的操作是区间修改单点查询,所以想用线段树,但是:TLE x8,WA x2。本人理解此算法理论复杂度O(N(logN)2)O(N(logN)^2)。

#include<bits/stdc++.h>
using namespace std;
#define ri register int
#define il inline
const long long out=1e18;
int a,b,c,d,e[200002],ful[200002];
long long pre[200002],dp[200002];
string in[200002];
struct node
{
	int left,right,num,lazy;
}str[800008];
il int lft(int x)
{
	return x<<1;
}
il int iht(int x)
{
	return x<<1|1;
}
il void pd(int x)
{
	if(str[x].lazy>0)
	{
		int lz=str[x].lazy;
		str[x].lazy=0;
		str[lft(x)].num=lz;
		str[lft(x)].lazy=lz;
		str[iht(x)].num=lz;
		str[iht(x)].lazy=lz;
	}
	return;
}
il long long got(int x,int y)
{
	long long rn=1,tc=abs(c-(pre[x]-pre[y]+(x-y-1))),al=d;//tc^d
	while(al>0)
	{
		if(al&1)
		{
			rn*=tc;
		}
		al>>=1;
		tc*=tc;
	}
	rn+=dp[y];
	return rn;
}
void makstr(int x,int lt,int rt)
{
	str[x].left=lt;
	str[x].right=rt;
	if(lt==rt)
	{
		return;
	}
	int me=(lt+rt)>>1;
	makstr(lft(x),lt,me);
	makstr(iht(x),me+1,rt);
	return;
}
void adstr(int x,int lt,int rt,int y)
{
	if(lt<=str[x].left&&str[x].right<=rt)
	{
		str[x].num=y;
		str[x].lazy=y;
		return;
	}
	pd(x);
	int me=(str[x].left+str[x].right)>>1;
	if(lt<=me)
	{
		adstr(lft(x),lt,rt,y);
	}
	if(rt>me)
	{
		adstr(iht(x),lt,rt,y);
	}
	return;
}
int foudstr(int x,int pl)
{
	if(str[x].left==str[x].right)
	{
		return str[x].num;
	}
	pd(x);
	int me=(str[x].left+str[x].right)>>1;
	if(pl<=me)
	{
		return foudstr(lft(x),pl);
	}
	else
	{
		return foudstr(iht(x),pl);
	}
}
il int twice(int x)
{
	int l,m=1,n=b;
	while(n-m>1)
	{
		l=(m+n)>>1;
		if(got(l,foudstr(1,l))<got(l,x))
		{
			m=l;
		}
		else
		{
			n=l;
		}
	}
	if(got(m,foudstr(1,m))>=got(m,x))
	{
		return m;
	}
	if(got(n,foudstr(1,n))>=got(n,x))
	{
		return n;
	}
	return n+1;
}
int main()
{
//	freopen("A.in","r",stdin);
	scanf("%d",&a);
	while(a--)
	{
		memset(dp,0x7f,sizeof(dp));
//		memset(str,0,sizeof(str));
		pre[0]=0;
		scanf("%d%d%d",&b,&c,&d);
		makstr(1,1,b);
		for(ri i=1;i<=b;i++)
		{
			cin>>in[i];
			e[i]=in[i].size();
			pre[i]=pre[i-1]+e[i];
		}
		dp[0]=0;
		for(ri i=1;i<=b;i++)
		{
			dp[i]=got(i,foudstr(1,i));
//			if(dp[i]<0||dp[i]>out)
//			{
//				dp[b]=dp[i];
//				break;
//			}
//			printf("i=%d  foud=%d\n",i,foudstr(1,i));
			int qwer=twice(i);
			if(qwer<=b)
			{
//				printf("i=%d  qwer=%d\n",i,qwer);
				adstr(1,qwer,b,i);
			}
		}
		if(dp[b]>out||dp[b]<0)
		{
			puts("Too hard to arrange");
			puts("--------------------");
		}
		else
		{
			printf("%lld\n",dp[b]);
			puts("--------------------");
		}
	}
	return 0;
}

希望可以知道自己错在了哪里。

2024/6/11 15:39
加载中...