1. 程式人生 > >2018.10.30模擬賽

2018.10.30模擬賽

T1 YY

YY 有一個大矩陣NM(N*M), 矩陣的每個格子裡都有一個整數權值W[i,j]W[i,j] 1<=i<=M,1<=j<=N(1<=i<=M,1<=j<=N) 對於這個矩陣YYYY會有PP次詢問,每次詢問這個大矩陣的一個子矩陣內的最大值。

solution:

據說是二維STST表裸題,然而我根本就不會STST

於是學習了一下,順便打了一下一維的模板

#include<iostream>
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define maxn 100005 using namespace std; int n,m,a[maxn],f[maxn][18]; inline int rd(){ int x=0,f=1;char c=' '; while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar(); while(c<='9' && c>='0') x=x*
10+c-'0',c=getchar(); return x*f; } inline void prework(){ for(int i=1;i<=n;i++) f[i][0]=a[i]; int t=log2(n); for(int j=1;j<=t;j++) for(int i=1;i<=n-(1<<j)+1;i++) f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); } inline int query(int l,int r){ int k=log2(r-l+1); return max
(f[l][k],f[r-(1<<k)+1][k]); } int main(){ n=rd(); m=rd(); for(int i=1;i<=n;i++) a[i]=rd(); prework(); while(m--){ int x=rd(),y=rd(); printf("%d\n",query(x,y)); } return 0; }

然後是這道二維的

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 305
using namespace std;
int n,m,q,a[maxn][maxn],f[maxn][maxn][10][10];

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}
inline int max(int x,int y){return x>y?x:y;}

inline void prework(){
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			f[i][j][0][0]=a[i][j];
	int t1=log2(n)+1,t2=log2(m)+1;
	for(int i=0;i<=t1;i++)
		for(int j=0;j<=t2;j++){
			if(!i && !j) continue;
			for(int x=1;x<=n-(1<<i)+1;x++)
				for(int y=1;y<=m-(1<<j)+1;y++)
					if(!i) f[x][y][i][j]=max(f[x][y][i][j-1],f[x][y+(1<<(j-1))][i][j-1]);
					else f[x][y][i][j]=max(f[x][y][i-1][j],f[x+(1<<(i-1))][y][i-1][j]);
		}
}

inline int query(int x1,int y1,int x2,int y2){
	int kx=log2(x2-x1+1),ky=log2(y2-y1+1);
	int ans=f[x1][y1][kx][ky];
	ans=max(ans,f[x1][y2-(1<<ky)+1][kx][ky]);
	ans=max(ans,f[x2-(1<<kx)+1][y1][kx][ky]);
	ans=max(ans,f[x2-(1<<kx)+1][y2-(1<<ky)+1][kx][ky]);
	return ans;
}

int main(){
	freopen("yy.in","r",stdin);
	freopen("yy.out","w",stdout);
	n=rd(); m=rd();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			a[i][j]=rd();
	prework(); q=rd();
	while(q--){
		int x1=rd(),y1=rd(),x2=rd(),y2=rd();
		printf("%d\n",query(x1,y1,x2,y2));
	}
	return 0;
}

看起來也不那麼難寫emmmemmm想不想知道我是怎麼做的?

單調棧預處理++分塊!複雜度O(n3+sqrt(n)q)O(n^3+sqrt(n)*q)好像跑的比正解快?

但是很卡空間,我卡到220+220+差不多,驚險過

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 301
#define inf 0x3f3f3f3f
using namespace std;
int n,m,Q,q[maxn],a[maxn][maxn],f[maxn][maxn][maxn],bel[maxn],ans;
int blo,tot,g[19][19][maxn][maxn],L[19],R[19];

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}
inline int min(int x,int y){return x<y?x:y;}
inline int max(int x,int y){return x>y?x:y;}

inline void prework(){
	int l,r,mx,i,j,now;
	for(i=1;i<=n;i++){//第i行
		for(j=1;j<=m;j++){//左端點 
			now=j+1; q[1]=a[i][j]; f[i][j][j]=a[i][j]; l=r=1;
			while(now<=m){
				while(l<=r && q[r]<a[i][now]) r--;
				q[++r]=a[i][now];
				f[i][j][now]=q[l]; now++;
			}
		}
	}
	blo=sqrt(n); tot=n/blo;
	for(i=1;i<=tot;i++){
		L[i]=(i-1)*blo+1; R[i]=i*blo;
		for(j=L[i];j<=R[i];j++) bel[j]=i;
	}
	if(R[tot]<n) tot++,L[tot]=R[tot-1]+1,R[tot]=n;
	for(i=L[tot];i<=R[tot];i++) bel[i]=tot;
	for(i=1;i<=m;i++)
		for(j=i;j<=m;j++){
			for(l=1;l<=tot;l++){
				mx=0;
				for(r=L[l];r<=R[l];r++)
					mx=max(mx,f[r][i][j]);
				g[l][l][i][j]=mx;
			}
			for(l=1;l<=tot;l++)
				for(r=l+1;r<=tot;r++)
					g[l][r][i][j]=max(g[l][r-1][i][j],g[r][r][i][j]);
		}
}

int main(){
	freopen("yy.in","r",stdin);
	freopen("yy.out","w",stdout);
	n=rd(); m=rd();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			a[i][j]=rd();
	prework();
	Q=rd();
	while(Q--){
		int x1=rd(),y1=rd(),x2=rd(),y2=rd();
		int l=bel[x1],r=bel
            
           

相關推薦

2018.10.30模擬

T1 YY YY 有一個大矩陣(N∗M)(N*M)(N∗M), 矩陣的每個格子裡都有一個整數權值W[i,j]W[i,j]W[i,j] (1&lt;=i&lt;=M,1&lt;=j

NOIP2014-10-30模擬

職責 std span con algo 思想 class 支持 可能 T1:逗比三角形 【題目描述】 小J是一名OI退役滾粗文化課選手,他十分喜歡做題,尤其是裸題。他現在有一個二維盒子和一些二維三角形,這個盒子擁有無限的高度和L的寬度。而且他的三角形也都是一些銳角三角形或

2018.10.24模擬2解題報告

個數 情況 不難 以及 是個 數組 std 方法 spa 心路歷程 預計得分:\(100 + (21 - 41) + 80\) 實際得分:\(100 + 21 + 43/44\)(評測機吃了一個subtask。。) 這套題應該是很有難度的,T1是個二維差分,開始沒看出來差點

2018.10.11模擬

T1 一道類似貪心的模擬題,就是要刪除一些讓min{a}∗min{b}min\{a\}*min\{b\}min{a}∗min{b}最大 可以先存兩個結構體,一個按aaa排序,一個按bbb排序,然後列舉a

noip 2018.10.14 模擬 砍樹

數學問題... 根據題意,有: 移項,整理,得: 記 於是 那麼 可以看到,最多隻會有2*個取值(顯而易見) 於是對應的,可能產生效果的d也只會有個,於是我們把他們找出來,扔進一個數組裡然後排序,去重,獲得的就是所有可能的取值 接下來,我們

2018.10.30 NOIp模擬 T1 改造二叉樹

【題目描述】       小Y在學樹論時看到了有關二叉樹的介紹:在電腦科學中,二叉樹是每個結點最多有兩個子結點的有序樹。通常子結點被稱作“左孩子”和“右孩子”。二叉樹被用作二叉搜尋樹和二叉堆。隨後他又和他人討論起了二叉搜尋樹。      什麼是二叉

【NOIP2018模擬2018.10.30

區間DP  明顯的序列合併操作,dalao們想到了區間DP  預處理0~7進行題目所示操作(實際上你會發現就是(a + b)/2)結果(O(1)算也可以),f[l][r][k]代表區間為[l,r]時,可以合併出k,轉移明顯是:  if(f[l1][r1][ki] &&

2018.10.30 NOIP模擬 字胡串(單調棧+容斥)

傳送門 對於每個點,用單調棧求出它左右第一個比他大的位置。 然後對每個點 O ( l

2018.10.30 NOIP模擬 有環無向圖(dijkstra+巧妙建圖)

傳送門 建圖巧妙啊。 對於每個點的出邊,我們將它們排序之後依次連邊。 這樣可以把 O (

2018.10.30 NOIP模擬 排列樹(樹形dp+組合數學)

傳送門 考試的時候亂搞過了。 其實題目就是讓你求拓撲排序方案數。 直接樹形 d p dp

【比賽報告】2018.10.30牛客網線上[ 牛客網NOIP賽前集訓營-提高組(第四場)] NOIP練習賽卷二十七

題目連結 A.動態點分治 模擬 題目連結 #include<cstdio> typedef long long ll; int t,find; ll l,r,k,x; int main() { //freopen("in.txt","r",stdin

【比賽報告】2018.10.30牛客網線上[牛客網NOIP賽前集訓營-提高組(第三場)] NOIP練習賽卷二十六

題目連結 A.管道維修 數學期望 題目連結 #include<cstdio> #include<algorithm> #include<cmath> using namespace std; typedef long long

【比賽報告】2018.10.30牛客網線上[牛客網NOIP賽前集訓營-提高組(第二場)] NOIP練習賽卷二十五

比賽連結 A.方差 字首和 題目連結 我們把方差公式進行化簡。記 s u

【比賽報告】2018.10.18校[2014-10-5NOIP模擬] NOIP練習賽卷十七

比賽時間:2018.10.18 選手:lrllrl 得分:100+90+20=210 用時:2小時 裸的LCA,隨你怎麼求,白送的分。 #include<cstdio> #include<algorithm> using name

2018/10/30 膜你 火柴

題目: 題目描述 P同學總共有k根火柴,分別放在擺成一列的n個火柴盒內,保證k是n的倍數。P同學想要每個火柴盒都有相同數目的火柴,每次他可以從一個火柴盒中拿一根火柴放到相鄰的火柴盒中。他想知道他最少要移

2014-5-10 NOIP模擬 by coolyangzc

[1] clas 表示 格式 不同的 tdi 命令 正整數 style Problem 1 機器人(robot.cpp/c/pas) 【題目描述】 早苗入手了最新的Gundam模型。最新款自然有著與以往不同的功能,那就是它能夠自動行走,厲害吧。 早苗的新模型可以按照輸

6.30模擬

ret 繼續 集合 ++ 新元素 != fff utility 文件包含 1.盤子序列(disk) 【題目描述】 有 n 個盤子。盤子被生產出來後,被按照某種順序摞在一起。初始盤堆中如果一 個盤子比所有它上面的盤子都大,那麽它是安全的,否則它是危險的。稱初始盤堆為

2017.10.18 模擬

click 合並 hid blob head mas fclose ble master 題目鏈接 T1 博弈論+概率dp 對於第一問:f[i][j]表示前i個數,當前黑板上的數為j的概率 當前有三種情況 1. 當前數不是j的倍數—>黑板上的數字改

10.23模擬

image ans img front 整數 最短路 strong font 次數 T1叉叉 題目描述 現在有一個字符串,每個字母出現的次數均為偶數。接下來我們把第一次出現的字母a和第二次出現的a連一條線,第三次出現的和四次出現的字母a連一條線,第五次出現的和六次出現的字母

2017-10-25模擬

open 貢獻 ans mod tro font operator owb 完成 T1 任務安排 容易發現 ans一定在0到min(s[i],t[i]) 的範圍內,二分這個最早時間,按著完成工作、 1 #include <algorithm>