蒟蒻0分求助
查看原帖
蒟蒻0分求助
195331
Mine_KingCattleya楼主2021/7/19 16:44

Rt,用的两个线段树,求大佬帮忙调一下kel,大概思路就是每遇到一个点就把他的值的位置变成 11,然后判断以这个点为中心的字符串是不是回文串。
其实就是参考的这里QwQ

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define MAXN 300005
#define int long long
using namespace std;
const int mod=1e9+7;
int n,power[300005];
struct segment_tree
{
	int l[MAXN*4],r[MAXN*4];
	int w[MAXN*4];
	void build(int k,int ll,int rr)
	{
		l[k]=ll,r[k]=rr;
		w[k]=0;
		if(ll==rr) return ;
		int mid=(ll+rr)/2;
		build(k*2,ll,mid);
		build(k*2+1,mid+1,rr);
		return ;
	}
	void change(int k,int x)
	{
		if(l[k]==r[k]){w[k]=1;return ;}
		int mid=(l[k]+r[k])/2;
		if(x<=mid) change(k*2,x);
		else change(k*2+1,x);
		w[k]=power[r[k*2+1]-l[k*2+1]+1]*w[k*2]%mod+w[k*2+1]%mod;
		return ;
	}
	pair<int,int>query(int k,int ll,int rr)
	{
		if(l[k]>=ll&&r[k]<=rr) return make_pair(w[k],r[k]-l[k]+1);
		int mid=(l[k]+r[k])/2;
		if(rr<=mid) return query(k*2,ll,rr);
		if(ll>mid) return query(k*2+1,ll,rr);
		pair<int,int>ansl=query(k*2,ll,rr),ansr=query(k*2+1,ll,rr);
		return make_pair((power[ansr.second]*ansl.first%mod+ansr.first)%mod,ansl.second+ansr.second);
	}
}tr,ee;
signed main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%lld",&n);
		power[0]=1;
		for(int i=1;i<=n;i++) power[i]=power[i-1]*23%mod;
		tr.build(1,1,n);
		ee.build(1,1,n);
		bool flag=false;
		for(int i=1;i<=n;i++)
		{
			int x;
			scanf("%lld",&x);
			int len=min(n-x,x-1);
			if(len>0&&tr.query(1,x-len,x-1).first!=ee.query(1,n-x-len+1/*n-(x+len)+1*/,n-x/*n-(x+1)+1*/).first)
			{
				puts("Y");
				flag=true;
				break;
			}
			tr.change(1,x);
			ee.change(1,n-x+1);
		}
		if(!flag) puts("N");
	}
	return 0;
}
2021/7/19 16:44
加载中...