CF1332E Height All the Same(思维)

矩阵高度统一的策略与计算
这是一篇关于CF1332E问题的解析,讨论了如何在n*m矩阵中通过特定操作使所有格子高度相等。文章指出,矩阵的奇偶性对是否能实现所有格子高度相等有决定性影响,并提供了相应的解决方案和计算方法。
部署运行你感兴趣的模型镜像

题意

有一个 n∗mn*mnm 的矩阵,每次可以往一个格子 +2+2+2,或在任意相邻的两个格子 +1+1+1,可以操作无限次。给定一个限制 [L,R][L,R][L,R],问有多少种初始情况满足 ai,j∈[L,R]a_{i,j}\in[L,R]ai,j[L,R],使得经过若干次操作后所有格子高度相等。

分析

日常感叹我太弱了。。。
首先,由于有 +2+2+2 操作,所以对于任意一个初始矩阵,都可以由一个 010101 矩阵不断 +2+2+2 转化而来。所以,我们其实只关心每个位置的奇偶性。
然后对于 +1+1+1 操作,相当于改变相邻两个格子的奇偶性,即是 000 变成 111111 变成 000
然后接下来有个重要的观察!

n∗mn*mnm 为奇数时,所有初始情况都可行!
为什么呢?当 n∗mn*mnm 为奇数时,一定有偶数个格子为 000111。下面考虑偶数个格子为 111 的情况(另一种情况与此等价)。翻转操作我们可以看成在走路。如果相邻位置是 010101,相当于交换 0,10,10,1 的位置;如果相邻位置是 111111,那么它们将相消。所以,两个 111 一定是可以相消的,即是从一个 111 走到另一个 111。于是,偶数个 111 格子一定可以化为 000
所以 ans=(R−L+1)nmans=(R-L+1)^{nm}ans=(RL+1)nm

那么 n∗mn*mnm 为偶数时呢?
可以发现,由上述观察,我们可以发现,满足条件为:有偶数个 000 格子和偶数个 111 格子,这样才可能消完 000111。假设 [L,R][L,R][L,R]xxx 个奇数, yyy 个偶数,那么我们枚举 111 格子的数量,有:
ans=∑i=0,2,4,...2kCnmi∗xi∗ynm−ians=\sum\limits_{i=0,2,4,...2k}C_ {nm}^i*x^i*y^{nm-i}ans=i=0,2,4,...2kCnmixiynmi
其实就是二项式定理取偶数项。
要得到 ansansans,只需要 ((x+y)nm+(x−y)nm)/2((x+y)^{nm}+(x-y)^{nm})/2((x+y)nm+(xy)nm)/2 就好了。

代码如下

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
const int mod = 998244353;
LL z = 1;
int read(){
	int x, f = 1;
	char ch;
	while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
	x = ch - '0';
	while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - 48;
	return x * f;
}
int ksm(int a, int b, int p){
	int s = 1;
	while(b){
		if(b & 1) s = z * s * a % p;
		a = z * a * a % p;
		b >>= 1;
	}
	return s;
}
int main(){
	int i, j, n, m, l, r, k, t, inv2;
	inv2 = ksm(2, mod - 2, mod);
	n = read(); m = read(); l = read(); r = read();
	k = (r - l + 1) / 2;
	if(l % 2 && r % 2) k++;
	t = (r - l + 1) - k;//k 为奇数的个数,t 为偶数的个数 
	if(n % 2 && m % 2){
		printf("%d", ksm(ksm(r - l + 1, n, mod), m, mod));
	}
	else{
		i = ksm(ksm(k + t, n, mod), m, mod);
		j = ksm(ksm(k - t, n, mod), m, mod);
		i = z * (i + j) * inv2 % mod;
		i = (i + mod) % mod;
		printf("%d", i);
	}
	return 0;
}

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) { // We've already done the navigation bar, status bar, and all screen decor windows. If the // status bar can receive input, we need to layout it again to accommodate for the IME // window. if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar || win == mNavigationBar || win == mCarDialLeft || win == mCarDialRight || mScreenDecorWindows.contains(win)) { return; } final WindowManager.LayoutParams attrs = win.getAttrs(); final int type = attrs.type; final int fl = PolicyControl.getWindowFlags(win, attrs); final int pfl = attrs.privateFlags; final int sim = attrs.softInputMode; final int requestedSysUiFl = 0; //PolicyControl.getSystemUiVisibility(null, attrs); final int sysUiFl = 0; // requestedSysUiFl | getImpliedSysUiFlagsForLayout(attrs); if(DEBUG_HUIDU){ Slog.d(TAG, "huidu add getsystemuivisibility type = " + type + " fl = " + fl + " pfl = " + pfl + " sim = " + sim + " requestedSysUiFl = " + requestedSysUiFl + " sysUiFl = " + sysUiFl); } if( win.getOwningPackage()!= null){ String pkg_bright = win.getOwningPackage(); // "com.android.systemui/com.android.systemui.settings.BrightnessDialog" if("com.android.systemui".equals(pkg_bright)){ Log.d(TAG, "huidu add layoutWindowLw systemui = " + win); return ; } } displayFrames = win.getDisplayFrames(displayFrames); final WindowFrames windowFrames = win.getWindowFrames(); sTmpLastParentFrame.set(windowFrames.mParentFrame); final Rect pf = windowFrames.mParentFrame; final Rect df = windowFrames.mDisplayFrame; final Rect cf = windowFrames.mContentFrame; final Rect vf = windowFrames.mVisibleFrame; final Rect dcf = windowFrames.mDecorFrame; final Rect sf = windowFrames.mStableFrame; dcf.setEmpty(); windowFrames.setParentFrameWasClippedByDisplayCutout(false); final boolean hasNavBar = hasNavigationBar() && ((mNavigationBar != null && mNavigationBar.isVisibleLw()) || (mCarDialLeft != null && mCarDialLeft.isVisibleLw()) || (mCarDialRight != null && mCarDialRight.isVisibleLw())); final int adjust = sim & SOFT_INPUT_MASK_ADJUST; final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) == FLAG_LAYOUT_IN_SCREEN; final boolean layoutInsetDecor = (fl & FLAG_LAYOUT_INSET_DECOR) == FLAG_LAYOUT_INSET_DECOR; sf.set(displayFrames.mStable); if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) { final @InsetsType int typesToFit = attrs.getFitInsetsTypes(); final @InsetsSide int sidesToFit = attrs.getFitInsetsSides(); final ArraySet<Integer> types = InsetsState.toInternalType(typesToFit); final Rect dfu = displayFrames.mUnrestricted; Insets insets = Insets.of(0, 0, 0, 0); for (int i = types.size() - 1; i >= 0; i--) { final InsetsSource source = mDisplayContent.getInsetsPolicy() .getInsetsForDispatch(win).peekSource(types.valueAt(i)); if (source == null) { continue; } insets = Insets.max(insets, source.calculateInsets( dfu, attrs.isFitInsetsIgnoringVisibility())); } int left = (sidesToFit & Side.LEFT) != 0 ? insets.left : 0; final int top = (sidesToFit & Side.TOP) != 0 ? insets.top : 0; int right = (sidesToFit & Side.RIGHT) != 0 ? insets.right : 0; final int bottom = (sidesToFit & Side.BOTTOM) != 0 ? insets.bottom : 0; final boolean isAppScren = true; // dfu 是显示器大小:dfu.right = 1920,dfu.bottom = 560 final String pkg = win.getOwningPackage(); if(DEBUG_HUIDU){ Log.w(TAG,"huidu add getOwningPackage = "+pkg); } if(pkg != null){ if(pkg.equals("com.android.systemui")){ return ; } } if(isAppScren){ // huidu add if(!"cn.huidu.lcd.player".equals(pkg) && !"cn.huidu.toolbox".equals(pkg)){ if(mCarDialLeft!=null && mCarDialLeft.isVisibleLw()){ left = getNavigationCarBarWidth(mCarDialLeft,displayFrames.mRotation,mDisplayContent.getConfiguration().uiMode); } if(mCarDialRight!=null && mCarDialRight.isVisibleLw()){ right = getNavigationCarBarWidth(mCarDialRight,displayFrames.mRotation,mDisplayContent.getConfiguration().uiMode); } } } if(DEBUG_HUIDU){ Log.w(TAG,"huidu add getOwningPackage left "+left+",top="+top+",right="+(dfu.right - right)+",bottom="+(dfu.bottom - bottom)); } df.set(left, top, dfu.right - right, dfu.bottom - bottom); // df.set(left, top, dfu.right - right, dfu.bottom - bottom); //df.set(400, top, 1520, dfu.bottom - bottom); /// HD CODE ADD special-shaped screen if (SystemProperties.getBoolean("ro.hd.special.screen", false)) { Slog.d(TAG, "huidu insets.left: " + insets.left + ", insets.top: " + insets.top + ", insets.right: " + insets.right + ", insets.bottom: " + insets.bottom); Slog.d(TAG, "huidu pkg: " + pkg); String mpkg = SystemProperties.get("persist.hd.display.packagename", "cn.huidu.lcd.player"); if (!pkg.equals(mpkg)) { /// HD CODE ADD 为什么要平移窗口内容,因为切割屏时,它是从左上角原往下 int mLeft = SystemProperties.getInt("ro.hd.display.left", 0); int mTop = SystemProperties.getInt("ro.hd.display.top", 0); int mRight = SystemProperties.getInt("ro.hd.display.right", 0); int mBottom = SystemProperties.getInt("ro.hd.display.bottom", 0); int navBarState = getNavBarState(mContext); int statusBarState = getStatusBarState(mContext); int navBarHeight = getNavigationBarHeight(displayFrames.mRotation, mDisplayContent.getConfiguration().uiMode); int statusBarHeight = getStatusBarHeight(displayFrames); Slog.d(TAG, " navBarState = " + navBarState + " navBarHeight = " + navBarHeight + " statusBarState = " + statusBarState + " statusBarHeight = " + statusBarHeight); if (navBarState == 1 && statusBarState == 0) { mTop -= statusBarHeight; } if (navBarState == 0) { mBottom += navBarHeight; } df.set(mLeft, mTop, dfu.right - mRight, dfu.bottom - mBottom); } Slog.d(TAG, "huidu dfu.left: " + dfu.left + ", dfu.top: " + dfu.top + ", dfu.right: " + dfu.right + ", dfu.bottom: " + dfu.bottom); } /// HD CODE END if (attached == null) { pf.set(df); if ((pfl & PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME) != 0) { final InsetsSource source = mDisplayContent.getInsetsPolicy() .getInsetsForDispatch(win).peekSource(ITYPE_IME); if (source != null) { pf.inset(source.calculateInsets(pf, false /* ignoreVisibility */)); } } vf.set(adjust != SOFT_INPUT_ADJUST_NOTHING ? displayFrames.mCurrent : displayFrames.mDock); } else { pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrameLw() : df); vf.set(attached.getVisibleFrameLw()); } cf.set(adjust != SOFT_INPUT_ADJUST_RESIZE ? displayFrames.mDock : displayFrames.mContent); dcf.set(displayFrames.mSystem); } else if (type == TYPE_INPUT_METHOD) { vf.set(displayFrames.mDock); cf.set(displayFrames.mDock); df.set(displayFrames.mDock); pf.set(displayFrames.mDock); // IM dock windows layout below the nav bar... pf.bottom = df.bottom = displayFrames.mUnrestricted.bottom; // ...with content insets above the nav bar cf.bottom = vf.bottom = displayFrames.mStable.bottom; if (mStatusBar != null && mFocusedWindow == mStatusBar && canReceiveInput(mStatusBar)) { // The status bar forces the navigation bar while it's visible. Make sure the IME // avoids the navigation bar in that case. if (mNavigationBarPosition == NAV_BAR_RIGHT) { pf.right = df.right = cf.right = vf.right = displayFrames.mStable.right; } else if (mNavigationBarPosition == NAV_BAR_LEFT) { pf.left = df.left = cf.left = vf.left = displayFrames.mStable.left; } } // In case the navigation bar is on the bottom, we use the frame height instead of the // regular height for the insets we send to the IME as we need some space to show // additional buttons in SystemUI when the IME is up. if (mNavigationBarPosition == NAV_BAR_BOTTOM) { final int rotation = displayFrames.mRotation; final int uimode = mService.mPolicy.getUiMode(); final int navHeightOffset = getNavigationBarFrameHeight(rotation, uimode) - getNavigationBarHeight(rotation, uimode); if (navHeightOffset > 0) { cf.bottom -= navHeightOffset; sf.bottom -= navHeightOffset; vf.bottom -= navHeightOffset; dcf.bottom -= navHeightOffset; } } // IM dock windows always go to the bottom of the screen. attrs.gravity = Gravity.BOTTOM; } else if (type == TYPE_VOICE_INTERACTION) { df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); if (adjust != SOFT_INPUT_ADJUST_RESIZE) { cf.set(displayFrames.mDock); } else { cf.set(displayFrames.mContent); } if (adjust != SOFT_INPUT_ADJUST_NOTHING) { vf.set(displayFrames.mCurrent); } else { vf.set(cf); } } else if (type == TYPE_WALLPAPER) { layoutWallpaper(displayFrames, pf, df, cf); } else if (type == TYPE_CAR_DIAL_LEFT) { // huidu update : 添加车载界面处理 df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); cf.set(displayFrames.mUnrestricted); vf.set(displayFrames.mUnrestricted); attrs.gravity = Gravity.LEFT; } else if (type == TYPE_CAR_DIAL_RIGHT) { // huidu update : 添加车载界面处理 df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); cf.set(displayFrames.mUnrestricted); vf.set(displayFrames.mUnrestricted); attrs.gravity = Gravity.RIGHT; } else if (win == mStatusBar || type == TYPE_NOTIFICATION_SHADE) { df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); cf.set(displayFrames.mStable); vf.set(displayFrames.mStable); if (adjust == SOFT_INPUT_ADJUST_RESIZE) { // cf.bottom should not be below the stable bottom, or the content might be obscured // by the navigation bar. if (cf.bottom > displayFrames.mContent.bottom) { cf.bottom = displayFrames.mContent.bottom; } } else { if (cf.bottom > displayFrames.mDock.bottom) { cf.bottom = displayFrames.mDock.bottom; } if (vf.bottom > displayFrames.mContent.bottom) { vf.bottom = displayFrames.mContent.bottom; } } } else { dcf.set(displayFrames.mSystem); final boolean isAppWindow = type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW; final boolean topAtRest = win == mTopFullscreenOpaqueWindowState && !win.isAnimatingLw(); if (isAppWindow && !topAtRest) { if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 && (fl & FLAG_FULLSCREEN) == 0 && (fl & FLAG_TRANSLUCENT_STATUS) == 0 && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0 && (pfl & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) == 0) { // Ensure policy decor includes status bar dcf.top = displayFrames.mStable.top; } if ((fl & FLAG_TRANSLUCENT_NAVIGATION) == 0 && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0 && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0 && (pfl & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) == 0) { // Ensure policy decor includes navigation bar dcf.bottom = displayFrames.mStable.bottom; dcf.right = displayFrames.mStable.right; } } if (layoutInScreen && layoutInsetDecor) { if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN, INSET_DECOR"); // This is the case for a normal activity window: we want it to cover all of the // screen space, and it can take care of moving its contents to account for screen // decorations that intrude into that space. if (attached != null) { // If this window is attached to another, our display // frame is the same as the one we are attached to. setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, cf, vf, displayFrames); } else { if (type == TYPE_STATUS_BAR_ADDITIONAL || type == TYPE_STATUS_BAR_SUB_PANEL) { // Status bar panels are the only windows who can go on top of the status // bar. They are protected by the STATUS_BAR_SERVICE permission, so they // have the same privileges as the status bar itself. // // However, they should still dodge the navigation bar if it exists. pf.left = df.left = hasNavBar ? displayFrames.mDock.left : displayFrames.mUnrestricted.left; pf.top = df.top = displayFrames.mUnrestricted.top; pf.right = df.right = hasNavBar ? displayFrames.mRestricted.right : displayFrames.mUnrestricted.right; pf.bottom = df.bottom = hasNavBar ? displayFrames.mRestricted.bottom : displayFrames.mUnrestricted.bottom; if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out status bar window: " + pf); } else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW || type == TYPE_VOLUME_OVERLAY || type == TYPE_KEYGUARD_DIALOG)) { // Asking for layout as if the nav bar is hidden, lets the application // extend into the unrestricted overscan screen area. We only do this for // application windows and certain system windows to ensure no window that // can be above the nav bar can do this. df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); } else { df.set(displayFrames.mRestricted); pf.set(displayFrames.mRestricted); } if ((fl & FLAG_FULLSCREEN) == 0) { if (win.isVoiceInteraction()) { cf.set(displayFrames.mVoiceContent); } else { // IME Insets are handled on the client for ADJUST_RESIZE in the new // insets world if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_NONE || adjust != SOFT_INPUT_ADJUST_RESIZE) { cf.set(displayFrames.mDock); } else { cf.set(displayFrames.mContent); } } } else { // Full screen windows are always given a layout that is as if the status // bar and other transient decors are gone. This is to avoid bad states when // moving from a window that is not hiding the status bar to one that is. cf.set(displayFrames.mRestricted); } applyStableConstraints(sysUiFl, fl, cf, displayFrames); if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE && adjust != SOFT_INPUT_ADJUST_NOTHING) { vf.set(displayFrames.mCurrent); } else { vf.set(cf); } } } else if (layoutInScreen || (sysUiFl & (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) { if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN"); // A window that has requested to fill the entire screen just // gets everything, period. if (type == TYPE_STATUS_BAR_ADDITIONAL || type == TYPE_STATUS_BAR_SUB_PANEL) { cf.set(displayFrames.mUnrestricted); df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); if (hasNavBar) { pf.left = df.left = cf.left = displayFrames.mDock.left; pf.right = df.right = cf.right = displayFrames.mRestricted.right; pf.bottom = df.bottom = cf.bottom = displayFrames.mRestricted.bottom; } if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out IN_SCREEN status bar window: " + pf); } else if (type == TYPE_NAVIGATION_BAR || type == TYPE_NAVIGATION_BAR_PANEL) { // The navigation bar has Real Ultimate Power. df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); if (DEBUG_LAYOUT) Slog.v(TAG, "Laying out navigation bar window: " + pf); } else if ((type == TYPE_SECURE_SYSTEM_OVERLAY || type == TYPE_SCREENSHOT) && ((fl & FLAG_FULLSCREEN) != 0)) { // Fullscreen secure system overlays get what they ask for. Screenshot region // selection overlay should also expand to full screen. cf.set(displayFrames.mUnrestricted); df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); } else if (type == TYPE_BOOT_PROGRESS) { // Boot progress screen always covers entire display. cf.set(displayFrames.mUnrestricted); df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); } else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && (type == TYPE_NOTIFICATION_SHADE || type == TYPE_TOAST || type == TYPE_DOCK_DIVIDER || type == TYPE_VOICE_INTERACTION_STARTING || (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW))) { // Asking for layout as if the nav bar is hidden, lets the // application extend into the unrestricted screen area. We // only do this for application windows (or toasts) to ensure no window that // can be above the nav bar can do this. // XXX This assumes that an app asking for this will also // ask for layout in only content. We can't currently figure out // what the screen would be if only laying out to hide the nav bar. cf.set(displayFrames.mUnrestricted); df.set(displayFrames.mUnrestricted); pf.set(displayFrames.mUnrestricted); } else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) { df.set(displayFrames.mRestricted); pf.set(displayFrames.mRestricted); // IME Insets are handled on the client for ADJUST_RESIZE in the new insets // world if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_NONE || adjust != SOFT_INPUT_ADJUST_RESIZE) { cf.set(displayFrames.mDock); } else { cf.set(displayFrames.mContent); } } else { cf.set(displayFrames.mRestricted); df.set(displayFrames.mRestricted); pf.set(displayFrames.mRestricted); } applyStableConstraints(sysUiFl, fl, cf, displayFrames); if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE && adjust != SOFT_INPUT_ADJUST_NOTHING) { vf.set(displayFrames.mCurrent); } else { vf.set(cf); } } else if (attached != null) { if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): attached to " + attached); // A child window should be placed inside of the same visible // frame that its parent had. setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, cf, vf, displayFrames); } else { if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): normal window"); // Otherwise, a normal window must be placed inside the content // of all screen decorations. if (type == TYPE_STATUS_BAR_ADDITIONAL) { // Status bar panels can go on // top of the status bar. They are protected by the STATUS_BAR_SERVICE // permission, so they have the same privileges as the status bar itself. cf.set(displayFrames.mRestricted); df.set(displayFrames.mRestricted); pf.set(displayFrames.mRestricted); } else if (type == TYPE_TOAST || type == TYPE_SYSTEM_ALERT) { // These dialogs are stable to interim decor changes. cf.set(displayFrames.mStable); df.set(displayFrames.mStable); pf.set(displayFrames.mStable); } else { pf.set(displayFrames.mContent); if (win.isVoiceInteraction()) { cf.set(displayFrames.mVoiceContent); df.set(displayFrames.mVoiceContent); } else if (adjust != SOFT_INPUT_ADJUST_RESIZE) { cf.set(displayFrames.mDock); df.set(displayFrames.mDock); } else { cf.set(displayFrames.mContent); df.set(displayFrames.mContent); } if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE && adjust != SOFT_INPUT_ADJUST_NOTHING) { vf.set(displayFrames.mCurrent); } else { vf.set(cf); } } } dcf.setEmpty() 如何修改应用窗口大小
最新发布
09-11
* This example program shows how 128 images of the interior of a church can be * combined into a mosaic that covers a 360x130 degree view. The images were acquired * with a camera in which the exposure and white balance were set to automatic. * Therefore, there are very large brightness and color differences between the images. * Hence, adjust_mosaic_images is used to align the images radiometrically. * Furthermore, blending is used to hide the transitions between the individual * images that make up the mosaic. dev_update_off () dev_close_window () dev_open_window (0, 0, 978, 324, 'black', WindowHandle) dev_set_part (0, 0, 647, 1955) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Reading images...') * Read the 128 images that make up the mosaic. gen_empty_obj (Images) for J := 1 to 128 by 1 read_image (Image, 'panorama/sankt_martin_automatic_' + J$'03d') concat_obj (Images, Image, Images) endfor get_image_size (Image, Width, Height) * Construct the tuples that determine which images should be matched. The * mosaic images were acquired as 16 vertical strips of 8 images each. * For each image, we match the image below the current image in the same * strip and the image to the left of the current image in the adjacent strip. FF := [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8] TT := [2,9,3,10,4,11,5,12,6,13,7,14,8,15,16] From := [] To := [] for J := 0 to 15 by 1 From := [From,(FF - 1 + 8 * J) % 128 + 1] To := [To,(TT - 1 + 8 * J) % 128 + 1] endfor * Initialize the data that is required for the self-calibration. HomMatrices2D := [] Rows1 := [] Cols1 := [] Rows2 := [] Cols2 := [] NumMatches := [] for J := 0 to |From| - 1 by 1 * Select the images to match. select_obj (Images, ImageF, From[J]) select_obj (Images, ImageT, To[J]) * Perform the point extraction of the images. points_foerstner (ImageF, 1, 2, 3, 50, 0.1, 'gauss', 'true', RowsF, ColsF, CoRRJunctions, CoRCJunctions, CoCCJunctions, RowArea, ColumnArea, CoRRArea, CoRCArea, CoCCArea) points_foerstner (ImageT, 1, 2, 3, 50, 0.1, 'gauss', 'true', RowsT, ColsT, CoRRJunctions1, CoRCJunctions1, CoCCJunctions1, RowArea1, ColumnArea1, CoRRArea1, CoRCArea1, CoCCArea1) concat_obj (ImageT, ImageF, ImageTF) tile_images_offset (ImageTF, TiledImage, [0,0], [0,Width + 20], [-1,-1], [-1,-1], [-1,-1], [-1,-1], 2 * Width + 20, Height) gen_cross_contour_xld (PointsF, RowsF, ColsF + Width + 20, 6, rad(45)) gen_cross_contour_xld (PointsT, RowsT, ColsT, 6, rad(0)) * Convert the images to gray value images. rgb1_to_gray (ImageF, ImageFG) rgb1_to_gray (ImageT, ImageTG) * Determine the projective transformation between the images. proj_match_points_ransac (ImageFG, ImageTG, RowsF, ColsF, RowsT, ColsT, 'ncc', 10, 0, 0, 648, 968, [rad(-10),rad(40)], 0.5, 'gold_standard', 10, 42, HomMat2D, Points1, Points2) * After this, we accumulate the required data. HomMatrices2D := [HomMatrices2D,HomMat2D] Rows1 := [Rows1,subset(RowsF,Points1)] Cols1 := [Cols1,subset(ColsF,Points1)] Rows2 := [Rows2,subset(RowsT,Points2)] Cols2 := [Cols2,subset(ColsT,Points2)] NumMatches := [NumMatches,|Points1|] * The rest of the code within the loop visualizes the point matches. RF := subset(RowsF,Points1) CF := subset(ColsF,Points1) + Width + 20 RT := subset(RowsT,Points2) CT := subset(ColsT,Points2) gen_empty_obj (Matches) for K := 0 to |RF| - 1 by 1 gen_contour_polygon_xld (Match, [RF[K],RT[K]], [CF[K],CT[K]]) concat_obj (Matches, Match, Matches) endfor dev_clear_window () dev_display (TiledImage) dev_set_color ('blue') dev_display (Matches) dev_set_color ('green') dev_display (PointsF) dev_display (PointsT) dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Matches between images ' + From[J]$'d' + ' and ' + To[J]$'d') endfor dev_clear_window () dev_set_window_extents (-1, -1, 856, 428) dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Performing self-calibration...') * Perform the self-calibration. stationary_camera_self_calibration (128, 968, 648, 6, From, To, HomMatrices2D, Rows1, Cols1, Rows2, Cols2, NumMatches, 'gold_standard', ['focus','principal_point','kappa'], 'true', CameraMatrix, Kappa, RotationMatrices, X, Y, Z, Error) dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Removing radial distortions...') * Remove the radial distortions from the images. cam_mat_to_cam_par (CameraMatrix, Kappa, 968, 648, CamParam) change_radial_distortion_cam_par ('fixed', CamParam, 0, CamParOut) gen_radial_distortion_map (Map, CamParam, CamParOut, 'bilinear') map_image (Images, Map, Images) dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Adjusting the images radiometrically...') * Before we adjust the images radiometrically, we compute the perspective * transformations between the images from the camera matrix and the rotation * matrices that are returned by the self-calibration. They are more accurate * than the perspective transformations that are returned by the matching * since they have been optimized over all images. For details on how the * perspective transformation matrices are computed by the code below, see the * documentation of stationary_camera_self_calibration. hom_mat2d_invert (CameraMatrix, CameraMatrixInv) PermMat := [0.0,1.0,0.5,1.0,0.0,0.5,0.0,0.0,1.0] hom_mat2d_invert (PermMat, PermMatInv) hom_mat2d_compose (CameraMatrixInv, PermMatInv, CamMatPermInv) hom_mat2d_compose (PermMat, CameraMatrix, CamMatPerm) HomMats2D := [] for J := 0 to |From| - 1 by 1 RotMatFrom := RotationMatrices[9 * (From[J] - 1):9 * (From[J] - 1) + 8] RotMatTo := RotationMatrices[9 * (To[J] - 1):9 * (To[J] - 1) + 8] hom_mat2d_transpose (RotMatFrom, RotMatFromInv) hom_mat2d_compose (RotMatTo, RotMatFromInv, RotMat) hom_mat2d_compose (RotMat, CamMatPermInv, RotCamMatInv) hom_mat2d_compose (CamMatPerm, RotCamMatInv, HomMat2D) HomMats2D := [HomMats2D,HomMat2D] endfor * Now adjust the images radiometrically. Since the exposure and white balance * were set to automatic, we calculate 'mult_gray'. Since the camera is a consumer * camera and therefore has a highly nonlinear response, we compute 'response'. * To compensate the vignetting in the images, we compute 'vignetting'. Finally, * to speed up the optimization, we use a subsampling by a factor of 4. adjust_mosaic_images (Images, CorrectedImages, From, To, 118, HomMats2D, 'gold_standard', ['mult_gray','response','vignetting','subsampling_4'], 'laguerre') * Since the reference image was not aligned perfectly horizontally, we modify the * calibrated rotation matrices by rotating them by -5.5 degrees around the x axis. hom_mat3d_identity (HomMat3D) hom_mat3d_rotate (HomMat3D, rad(-5.5), 'x', 0, 0, 0, HomMat3D) RotMat := [HomMat3D[0:2],HomMat3D[4:6],HomMat3D[8:10]] RotMats := [] for J := 0 to 127 by 1 RotMatCalib := RotationMatrices[J * 9:J * 9 + 8] hom_mat2d_compose (RotMatCalib, RotMat, RotMatRot) RotMats := [RotMats,RotMatRot] endfor dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Creating spherical mosaic of the original images...') * Create the spherical mosaic of the original images. gen_spherical_mosaic (Images, SphericalMosaicOrig, CameraMatrix, RotMats, -90, 90, -180, 180, 0, 'voronoi', 'bilinear') get_image_size (SphericalMosaicOrig, Width, Height) dev_set_part (0, 0, Height - 1, Width - 1) dev_clear_window () dev_display (SphericalMosaicOrig) dev_set_color ('yellow') set_tposition (WindowHandle, Height - 300, 20) write_string (WindowHandle, 'Spherical mosaic of the original images') set_tposition (WindowHandle, Height - 150, 20) write_string (WindowHandle, 'Press \'Run\' to continue') stop () dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Creating spherical mosaic of the radiometrically adjusted images...') * Create the spherical mosaic of the radiometrically adjusted images. gen_spherical_mosaic (CorrectedImages, SphericalMosaicAdjust, CameraMatrix, RotMats, -90, 90, -180, 180, 0, 'voronoi', 'bilinear') get_image_size (SphericalMosaicAdjust, Width, Height) dev_set_part (0, 0, Height - 1, Width - 1) dev_clear_window () dev_display (SphericalMosaicAdjust) dev_set_color ('yellow') set_tposition (WindowHandle, Height - 300, 20) write_string (WindowHandle, 'Spherical mosaic of the radiometrically adjusted images') set_tposition (WindowHandle, Height - 150, 20) write_string (WindowHandle, 'Press \'Run\' to continue') stop () dev_clear_window () dev_set_color ('yellow') set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Creating blended spherical mosaic of the radiometrically adjusted images...') * Create the blended spherical mosaic of the radiometrically adjusted images. gen_spherical_mosaic (CorrectedImages, SphericalMosaicAdjustBlend, CameraMatrix, RotMats, -90, 90, -180, 180, 0, 'blend', 'bilinear') get_image_size (SphericalMosaicAdjustBlend, Width, Height) dev_set_part (0, 0, Height - 1, Width - 1) dev_clear_window () dev_display (SphericalMosaicAdjustBlend) dev_set_color ('yellow') set_tposition (WindowHandle, Height - 300, 20) write_string (WindowHandle, 'Blended spherical mosaic of the radiometrically adjusted images')
06-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值