首页 > 其他分享 >【题解】[FJOI2017]矩阵填数

【题解】[FJOI2017]矩阵填数

时间:2023-02-02 19:33:45浏览次数:48  
标签:le return int 题解 矩阵 填数 res FJOI2017 mod

题目分析:

最大值为 \(v\) 的限制显然可以转化为 \(\le v\) 的方案数减去 \(\le v-1\) 的方案数。
因为这里有很多个这种限制所以直接容斥就好了,具体来说就是枚举哪些条件取 \(\le v-1\) 那么剩下的就取 \(\le v\),取 \(n=1\) 手算一下就可以得到容斥系数为 \((-1)^{|S|}\)。
因为 \(n \le 10\) 所以其实对于某一种情况求方案直接暴力就可以了,我们可以将矩阵离散化,这样会用到的点就只有 \(O(n)\) 个,我们可以对于每一个位置求一下其取值范围,下界显然就是 \(1\) 了,而对于上界我们其实就可以将这些限制从紧到松去取,也就是从小到大排序,然后每次进行一个矩阵赋值和矩阵求和,这样限制出来显然是正确的。

代码:

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 105;
const int MOD = 1e9+7;
struct node{
	int l1,l2,r1,r2,v;
}a[N],b[N];
int cnt[N][N],l[N],r[N];
bool vis[N][N];
int mod(int x){
	return x % MOD;
}
int power(int a,int b){
	int res = 1;
	while(b){
		if(b & 1)	res = mod(res * a);
		a = mod(a * a);
		b >>= 1;
	}
	return res;
}
bool cmp(node a,node b){
	return a.v < b.v;
}
int calc(int l1,int r1,int l2,int r2){
	int res = 0;
	for(int i=l1; i<l2; i++){
		for(int j=r1; j<r2; j++){
			if(!vis[i][j]){
				res += cnt[i][j];
				vis[i][j] = true;
			}
		}
	}
	return res;
}
signed main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	int T;scanf("%lld",&T);
	while(T--){
		memset(cnt,0,sizeof(cnt));memset(vis,false,sizeof(vis));
		int n,m,limit,h;scanf("%lld%lld%lld%lld",&n,&m,&limit,&h);
		int cnt1 = 0,cnt2 = 0;
		l[++cnt1] = 1;l[++cnt1] = n+1;
		r[++cnt2] = 1;r[++cnt2] = m+1;
		for(int i=1; i<=h; i++){
			scanf("%lld%lld%lld%lld%lld",&a[i].l1,&a[i].r1,&a[i].l2,&a[i].r2,&a[i].v);
			a[i].l2++,a[i].r2++;
			l[++cnt1] = a[i].l1;l[++cnt1] = a[i].l2;
			r[++cnt2] = a[i].r1;r[++cnt2] = a[i].r2;
		}
		sort(l+1,l+cnt1+1);sort(r+1,r+cnt2+1);
		cnt1 = unique(l+1,l+cnt1+1) - l - 1;
		cnt2 = unique(r+1,r+cnt2+1) - r - 1;
		for(int i=1; i<=h; i++){
			a[i].l1 = lower_bound(l+1,l+cnt1+1,a[i].l1) - l;
			a[i].r1 = lower_bound(r+1,r+cnt2+1,a[i].r1) - r;
			a[i].l2 = lower_bound(l+1,l+cnt1+1,a[i].l2) - l;
			a[i].r2 = lower_bound(r+1,r+cnt2+1,a[i].r2) - r;
		}
		for(int i=1; i<cnt1; i++){  //我们将每一个点代表它右下角的这一块 
			for(int j=1; j<cnt2; j++){
				cnt[i][j] = mod((l[i+1] - l[i]) * (r[j+1] - r[j]));
			}
		}
		int ans = 0;
		for(int S=0; S<(1<<h); S++){
			for(int i=1; i<cnt1; i++){
				for(int j=1; j<cnt2; j++){
					vis[i][j] = false;
				}
			}
			int res = 1;
			for(int i=1; i<=h; i++){
				b[i] = a[i];
				if((S >> (i-1)) & 1)	b[i].v--;
			}
			sort(b+1,b+h+1,cmp);
			for(int i=1; i<=h; i++)	res = mod(res * power(b[i].v,calc(b[i].l1,b[i].r1,b[i].l2,b[i].r2)));
			for(int i=1; i<cnt1; i++){
				for(int j=1; j<cnt2; j++){
					if(vis[i][j])	continue;
					res = mod(res * power(limit,cnt[i][j]));
				}
			}
			if(__builtin_parity(S))	ans = mod(ans + (MOD-1) * res);
			else	ans = mod(ans + res);	
		}
		printf("%lld\n",ans);
	}
	return 0;
}

标签:le,return,int,题解,矩阵,填数,res,FJOI2017,mod
From: https://www.cnblogs.com/linyihdfj/p/17087184.html

相关文章

  • 【题解】Luogu DTOI Round 4
    前言:好久不打洛谷的\(rated\)赛了,结果一打\(205,rk14\),看来是没有大佬来打。放一下链接:https://www.luogu.com.cn/contest/96429P8976「DTOI-4」排列题目分析:这个......
  • CF1037H Security题解
    根据字典序的定义,位置大的大于长度长的,长度长的大于长度短的。所以我们贪心,先追求长度长的,再追求后面的位置大的,再追求前面的位置大的。我们要一个能遍历子串的结构,就选......
  • 关于“等保保护”最常见问题解答!
    等保全称信息安全等级保护,它是网络安全体系中非常重要的组成部分。但很多人对等保不够了解,所以小编特整理了这篇文章,希望对你们有帮助。1、等级保护是强制性的吗?可......
  • 【题解】CF1770F Koxia and Sequence
    有没有觉得其他题解的模二Lucas逆用太智慧了,有没有觉得这题的第一思路是直接拆位算每一位是否有贡献,而不是先满足和的限制列式?这里提供另外一个做法。方向不同,结果一样......
  • Codeforces Round #848 (Div. 2) A~F 题解
    A.FlipFlopSum能换\(-1,-1\)就换,不能能换\(1,-1\)或\(-1,1\)也可以,否则只能换\(1,1\)。B.TheForbiddenPermutation如果原序列一开始就是好的那就结束,否则......
  • 关于github上README.md图片显示不出来的问题解决办法
    关于github上README.md图片显示不出来的问题解决办法出现原因:如果你的README文件内显示图片的路径是正确的,那么很有可能是因为DNS被污染了所以导致显示不正常,即无法访问存放......
  • 【PER #1】捉迷藏 / Ptz2022 Day1.Kyoto U L 题解
    今天心血来潮想改一改pj的题,发现了这场easyround的A还没改……跟自己和解了,想了两天没想明白,说说大致思路。题目链接只考虑一组询问怎么做,先把\(v\)当作根,称......
  • i.MX6ULL - 问题解决:NFS挂载失败 - VFS: Unable to mount root fs on unknown-block(2
    i.IMX6ULL-问题解决:NFS挂载失败-VFS:Unabletomountrootfsonunknown-block(2,0)开发环境:移植的linux5.4.7.0ubuntu1804x64arm-linux-gnueabihf-gccv7.5NFS方式......
  • Qt | QListWidgetItem返回错误的背景颜色(始终返回颜色值为0)问题解决
    Qt|QListWidgetItem返回错误的背景颜色(始终返回颜色值为0)问题解决使用场景:程序使用QListWidget显示一个列表,这个列表具有点击选择和再次点击取消选择的功能,点击之后需要更......
  • SOJ1728 题解
    题意有一个长度为\(n\)的数列\(a_0,a_1,\dots,a_{n-1}\)以及一个长度为\(m\)的操作序列\((b_0,c_0),(b_1,c_1)\dots(b_{m-1},c_{m-1})\)。执行\(t\)次操作,第\(......