在一个2^k×2^k个方格组成的棋盘中恰有一个方格与其它方格不同(图中标记为-1的方格),称之为特殊方格。现用L型(占3个小方格)纸片覆盖棋盘上除特殊方格的所有部分,各纸片不得重叠,于是,用到的纸片数恰好是(4^k-1)/3。在下表给出的一个覆盖方案中,k=2,相同的3各数字构成一个纸片。
下面使用分治法设计的,将棋盘一分为四,依次处理左上角、右上角、左下角、右下角,递归进行。输出最后的棋盘。
标签:else 表示 棋盘 using i++ 卖出 维护 inpu getchar
【数据范围】
50%的数据k<=5。
100%的数据k<=10。
题解:分治,将原问题分为形式相同,规模更小的子问题。
将棋盘分成4份,在中间交界构造出一块纸片,使得每块里均有一个特殊方格。
1 #include <iostream> 2 #include <cstdio> 3 #define N 2100 4 using namespace std; 5 int map[N][N],n,bx,by,cnt; 6 void dfs(int x,int y,int xx,int yy,int k) 7 { 8 if (x+1==xx) 9 { 10 ++cnt; 11 if (k!=1) map[x][y]=cnt; 12 if (k!=2) map[x][yy]=cnt; 13 if (k!=3) map[xx][y]=cnt; 14 if (k!=4) map[xx][yy]=cnt; 15 return; 16 } 17 int ox=(x+xx)>>1,oy=(y+yy)>>1,o=(xx-x+1)>>2,po,temp; 18 if (k==0) 19 { 20 if (bx<=ox && by<=oy) po=1; 21 else if (bx<=ox) po=2; 22 else if (by<=oy) po=3; 23 else po=4; 24 dfs(ox-o+1,oy-o+1,ox+o,oy+o,po); 25 if (po==1) temp=0;else temp=4; 26 dfs(x,y,ox,oy,temp); 27 if (po==2) temp=0;else temp=3; 28 dfs(x,oy+1,ox,yy,temp); 29 if (po==3) temp=0;else temp=2; 30 dfs(ox+1,y,xx,oy,temp); 31 if (po==4) temp=0;else temp=1; 32 dfs(ox+1,oy+1,xx,yy,temp); 33 } 34 else 35 { 36 dfs(ox-o+1,oy-o+1,ox+o,oy+o,k); 37 if (k!=1) dfs(x,y,ox,oy,4); 38 if (k!=2) dfs(x,oy+1,ox,yy,3); 39 if (k!=3) dfs(ox+1,y,xx,oy,2); 40 if (k!=4) dfs(ox+1,oy+1,xx,yy,1); 41 } 42 } 43 void solve() 44 { 45 cin>>n>>bx>>by; 46 n=1<<n; 47 dfs(1,1,n,n,0); 48 } 49 void print() 50 { 51 map[bx][by]=-1; 52 for (int i=1;i<=n;++i) 53 for (int j=1;j<=n;++j) 54 if (j<n) printf("%d ",map[i][j]); 55 else printf("%d\n",map[i][j]); 56 } 57 int main() 58 { 59 solve(); 60 print(); 61 return 0; 62 }
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<cstdlib> 7 #include<vector> 8 using namespace std; 9 typedef long long ll; 10 typedef long double ld; 11 typedef pair<int,int> pr; 12 const double pi=acos(-1); 13 #define rep(i,a,n) for(int i=a;i<=n;i++) 14 #define per(i,n,a) for(int i=n;i>=a;i--) 15 #define Rep(i,u) for(int i=head[u];i;i=Next[i]) 16 #define clr(a) memset(a,0,sizeof(a)) 17 #define pb push_back 18 #define mp make_pair 19 #define fi first 20 #define sc second 21 #define pq priority_queue 22 #define pqb priority_queue <int, vector<int>, less<int> > 23 #define pqs priority_queue <int, vector<int>, greater<int> > 24 #define vec vector 25 ld eps=1e-9; 26 ll pp=1000000007; 27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} 28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} 29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); } 30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; } 31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; 32 ll read(){ ll ans=0; char last=‘ ‘,ch=getchar(); 33 while(ch<‘0‘ || ch>‘9‘)last=ch,ch=getchar(); 34 while(ch>=‘0‘ && ch<=‘9‘)ans=ans*10+ch-‘0‘,ch=getchar(); 35 if(last==‘-‘)ans=-ans; return ans; 36 } 37 int n,m; 38 #define N 3000 39 #define lowbit(i) (i&(-i)) 40 int t_1[N][N],t_2[N][N],t_3[N][N],t_4[N][N]; 41 void add(int x,int y,int v_1,int v_2,int v_3,int v_4){ 42 for (int i=x;i<=n;i+=lowbit(i)) 43 for (int j=y;j<=m;j+=lowbit(j)) t_1[i][j]+=v_1,t_2[i][j]+=v_2,t_3[i][j]+=v_3,t_4[i][j]+=v_4; 44 } 45 int sum(int x,int y){ 46 int Sum1=0,Sum2=0,Sum3=0,Sum4=0; 47 for (int i=x;i>0;i-=lowbit(i)) 48 for (int j=y;j>0;j-=lowbit(j)) Sum1+=t_1[i][j],Sum2+=t_2[i][j],Sum3+=t_3[i][j],Sum4+=t_4[i][j]; 49 return Sum1*x*y-Sum2*x-Sum3*y+Sum4; 50 } 51 int main() 52 { 53 char ch[10]; scanf("%s%d%d",ch,&n,&m); 54 while (~scanf("%s",ch)){ 55 if (ch[0]==‘L‘){ 56 int a,b,c,d,v; scanf("%d%d%d%d%d",&a,&b,&c,&d,&v); 57 add(a,b,v,v*(b-1),v*(a-1),v*(a-1)*(b-1)); add(a,d+1,-v,(-v)*d,(-v)*(a-1),(-v)*d*(a-1)); 58 add(c+1,b,-v,(-v)*(b-1),(-v)*c,(-v)*c*(b-1)); add(c+1,d+1,v,v*d,v*c,v*d*c); 59 } else { 60 int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); 61 printf("%d\n",sum(c,d)-sum(a-1,d)-sum(c,b-1)+sum(a-1,b-1)); 62 } 63 } 64 return 0; 65 }
类似RMQ问题(可以用ST表解决):
最小买入价格Mi[i][j] = min(Mi[i][j - 1]; Mi[i + 2j-1][j - 1]);
最大卖出价格Mx[i][j] = max(Mx[i][j - 1]; Mx[i + 2j-1][j - 1]);
最大收益F[i][j] = maxfF[i][j - 1]; F[i + 2j-1][j - 1],Mx[i + 2j-1][j - 1] - Mi[i][j - 1];
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<cstdlib> 7 #include<vector> 8 using namespace std; 9 typedef long long ll; 10 typedef long double ld; 11 typedef pair<int,int> pr; 12 const double pi=acos(-1); 13 #define rep(i,a,n) for(int i=a;i<=n;i++) 14 #define per(i,n,a) for(int i=n;i>=a;i--) 15 #define Rep(i,u) for(int i=head[u];i;i=Next[i]) 16 #define clr(a) memset(a,0,sizeof(a)) 17 #define pb push_back 18 #define mp make_pair 19 #define fi first 20 #define sc second 21 #define pq priority_queue 22 #define pqb priority_queue <int, vector<int>, less<int> > 23 #define pqs priority_queue <int, vector<int>, greater<int> > 24 #define vec vector 25 ld eps=1e-9; 26 ll pp=1000000007; 27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} 28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} 29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); } 30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; } 31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; 32 ll read(){ ll ans=0; char last=‘ ‘,ch=getchar(); 33 while(ch<‘0‘ || ch>‘9‘)last=ch,ch=getchar(); 34 while(ch>=‘0‘ && ch<=‘9‘)ans=ans*10+ch-‘0‘,ch=getchar(); 35 if(last==‘-‘)ans=-ans; return ans; 36 } 37 int n,m; 38 int f_a[500005][20],f_i[500005][20],f[500005][20]; 39 void Build(){ 40 for (int i=1;i<=n;i++) { 41 scanf("%d",&f_a[i][0]); f_i[i][0]=f_a[i][0]; f[i][0]=0; 42 } 43 for (int j=1;(1<<j)<n;j++) 44 for (int i=1;i+(1<<j)-1<=n;i++){ 45 f_a[i][j]=max(f_a[i][j-1],f_a[i+(1<<(j-1))][j-1]); 46 f_i[i][j]=min(f_i[i][j-1],f_i[i+(1<<(j-1))][j-1]); 47 f[i][j]=max(max(f[i][j-1],f[i+(1<<(j-1))][j-1]),f_a[i+(1<<(j-1))][j-1]-f_i[i][j-1]); 48 } 49 } 50 int Query_(int a,int b){ 51 if (a>b) return 0; 52 int k=(int)((log(b-a+1)*1.0)/(log(2))); 53 return max(f_a[a][k],f_a[b-(1<<k)+1][k]); 54 } 55 int Query(int a,int b){ 56 if (a>=b) return 0; 57 int k=(int)((log(b-a+1)*1.0)/(log(2))); 58 return max(f[a][k],max(Query(a+(1<<k),b),Query_(a+(1<<k),b)-f_i[a][k])); 59 } 60 int main() 61 { 62 scanf("%d%d",&n,&m); 63 Build(); 64 while (m--){ 65 int a,b; scanf("%d%d",&a,&b); 66 printf("%d\n",Query(a,b)); 67 } 68 return 0; 69 }
输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
splay老题了,代码量有点大,所以,,就不上代码了我不会告诉你们我懒得写。
标签:else 表示 棋盘 using i++ 卖出 维护 inpu getchar
原文地址:http://www.cnblogs.com/SXia/p/6863626.html