QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#80111#1268. Diamond RusheyiigjknAC ✓2662ms148100kbC++143.6kb2023-02-22 12:05:402023-02-22 12:05:41

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-02-22 12:05:41]
  • 评测
  • 测评结果:AC
  • 用时:2662ms
  • 内存:148100kb
  • [2023-02-22 12:05:40]
  • 提交

answer

# include <bits/stdc++.h>
using namespace std;
using ll=long long;
using Hash=pair<int,int>;
constexpr int p1=1e9+7,p2=1e9+9,Base=998244353;
inline Hash operator+(const Hash &x,const Hash &y){return {(x.first+y.first)%p1,(x.second+y.second)%p2};}
inline Hash &operator+=(Hash &x,const Hash &y){return x=x+y;}
inline Hash operator-(const Hash &x,const Hash &y){return {(x.first+p1-y.first)%p1,(x.second+p2-y.second)%p2};}
inline Hash operator*(const Hash &x,const Hash &y){return {(ll)x.first*y.first%p1,(ll)x.second*y.second%p2};}
int N,a[410][410],f[410][410],g[410][410],pwn[160010],lc[20000010],rc[20000010],cnt[20000010],sum[20000010],tot=0;
Hash pw[160010],pre[410][410],suf[410][410],val[20000010];
template<typename T>
inline void upd(int &x,const T &y){x=(x+y)%p1;}
inline Hash Lc(const Hash &rt){return {lc[rt.first],lc[rt.second]};}
inline Hash Rc(const Hash &rt){return {rc[rt.first],rc[rt.second]};}
inline int Cnt(const Hash &rt){return cnt[rt.first]+cnt[rt.second];}
inline int Sum(const Hash &rt){return (sum[rt.first]+sum[rt.second])%p1;}
inline Hash Val(const Hash &rt){return val[rt.first]+val[rt.second];}
void pushup(int rt)
{
	sum[rt]=(sum[lc[rt]]+sum[rc[rt]])%p1;
	val[rt]=val[lc[rt]]+val[rc[rt]];
}
void update(int &rt,int l,int r,int x)
{
	int cur=++tot;
	lc[cur]=lc[rt];rc[cur]=rc[rt];cnt[cur]=cnt[rt];sum[cur]=sum[rt];val[cur]=val[rt];rt=cur;
	if(l==r) return cnt[rt]++,upd(sum[rt],pwn[l]),val[rt]+=pw[l],void();
	int mid=(l+r)/2;
	if(x<=mid) update(lc[rt],l,mid,x);
	else update(rc[rt],mid+1,r,x);
	pushup(rt);
}
bool cmp(int r1,int r2,int l,int r)
{
	if(!r1) return false;
	else if(!r2) return true;
	if(l==r) return cnt[r1]>cnt[r2];
	int mid=(l+r)/2;
	if(val[rc[r1]]!=val[rc[r2]]) return cmp(rc[r1],rc[r2],mid+1,r);
	else return cmp(lc[r1],lc[r2],l,mid);
}
bool cmp(const Hash &r1,const Hash &r2,int l,int r)
{
	if(!r1.first && !r1.second) return false;
	else if(!r2.first && !r2.second) return true;
	if(l==r) return Cnt(r1)>Cnt(r2);
	int mid=(l+r)/2;
	if(Val(Rc(r1))!=Val(Rc(r2))) return cmp(Rc(r1),Rc(r2),mid+1,r);
	else return cmp(Lc(r1),Lc(r2),l,mid);
}
int main()
{
	int T,n,q,x1,x2,y1,y2;
	cin>>T;
	while(T--)
	{
		scanf("%d%d",&n,&q);N=n*n;
		pwn[0]=1;
		for(int i=1;i<=N;i++) pwn[i]=(ll)pwn[i-1]*N%p1;
		pw[0]={1,1};
		for(int i=1;i<=N;i++) pw[i]=pw[i-1]*Hash{Base,Base};
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				scanf("%d",&a[i][j]);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				if(i==1 && j==1) f[i][j]=0;
				else if(i==1) f[i][j]=f[i][j-1];
				else if(j==1) f[i][j]=f[i-1][j];
				else f[i][j]=(cmp(f[i][j-1],f[i-1][j],1,N)?f[i][j-1]:f[i-1][j]);
				update(f[i][j],1,N,a[i][j]);
			}
		for(int i=n;i;i--)
			for(int j=n;j;j--)
			{
				if(i==n && j==n) g[i][j]=0;
				else if(i==n) g[i][j]=g[i][j+1];
				else if(j==n) g[i][j]=g[i+1][j];
				else g[i][j]=(cmp(g[i][j+1],g[i+1][j],1,N)?g[i][j+1]:g[i+1][j]);
				pre[i][j]=suf[i][j]={f[i][j],g[i][j]};
				update(g[i][j],1,N,a[i][j]);
			}
		for(int i=1;i<=n;i++)
		{
			for(int j=2;j<=n;j++) pre[i][j]=(cmp(pre[i][j],pre[i][j-1],1,N)?pre[i][j]:pre[i][j-1]);
			for(int j=n-1;j;j--) suf[i][j]=(cmp(suf[i][j],suf[i][j+1],1,N)?suf[i][j]:suf[i][j+1]);
		}
		while(q--)
		{
			Hash ans={0,0};
			scanf("%d%d%d%d",&x1,&x2,&y1,&y2);
			if(x2<n && y1>1) ans=(cmp(ans,pre[x2+1][y1-1],1,N)?ans:pre[x2+1][y1-1]);
			if(x1>1 && y2<n) ans=(cmp(ans,suf[x1-1][y2+1],1,N)?ans:suf[x1-1][y2+1]);
			printf("%d\n",Sum(ans));
		}
		memset(lc+1,0,sizeof(int)*tot);
		memset(rc+1,0,sizeof(int)*tot);
		memset(cnt+1,0,sizeof(int)*tot);
		memset(sum+1,0,sizeof(int)*tot);
		memset(val+1,0,sizeof(Hash)*tot);
		tot=0;
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 5668kb

input:

1
2 2
2 3
1 4
1 1 2 2
2 2 1 1

output:

276
336

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 2662ms
memory: 148100kb

input:

5
399 200000
1 5 3 2 3 5 5 4 3 5 2 5 1 2 4 1 3 1 1 5 5 5 5 2 2 2 3 3 5 3 5 3 1 2 3 2 3 3 4 3 5 3 1 3 4 5 2 1 4 4 5 4 5 3 3 2 4 2 3 5 1 2 4 4 3 2 3 5 4 4 1 2 3 5 5 2 1 5 5 1 4 1 2 5 3 4 5 3 5 5 5 3 2 3 1 2 1 1 2 5 1 4 1 3 4 1 1 3 5 3 2 2 3 1 3 1 3 1 5 1 4 1 1 2 5 1 4 3 1 3 2 5 4 2 3 5 5 2 5 3 1 5 3 1...

output:

941207053
72597563
125162256
674945829
362141056
46633728
833089835
282730934
340464097
953149538
282730934
736432213
513486467
333152891
355535008
797175106
144845122
87755843
408404885
635578224
670481364
176200794
282730934
733794083
302174217
658772773
282730934
556675047
149516187
282730934
362...

result:

ok 1000000 lines